xmlsecurityengine/xmlsec/src/xmlsec_xkms.c
changeset 0 e35f40988205
child 8 e65204f75c47
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /** 
       
     2  * XML Security Library (http://www.aleksey.com/xmlsec).
       
     3  *
       
     4  * "XML Key Management Specification v 2.0" implementation
       
     5  *  http://www.w3.org/TR/xkms2/
       
     6  * 
       
     7  * This is free software; see Copyright file in the source
       
     8  * distribution for preciese wording.
       
     9  * 
       
    10  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
       
    11  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    12  */
       
    13 
       
    14 #include "xmlsec_config.h"
       
    15 #ifndef XMLSEC_NO_XKMS
       
    16 #include "xmlsec_globals.h"
       
    17  
       
    18 #include <stdlib.h>
       
    19 #include <stdio.h>
       
    20 #include <string.h>
       
    21 
       
    22 #include <libxml2_tree.h>
       
    23 #include <libxml2_parser.h>
       
    24 #include <libxml2_globals.h>
       
    25 
       
    26 #include "xmlsec_xmlsec.h"
       
    27 #include "xmlsec_buffer.h"
       
    28 #include "xmlsec_xmltree.h"
       
    29 #include "xmlsec_keys.h"
       
    30 #include "xmlsec_keysmngr.h"
       
    31 #include "xmlsec_transforms.h"
       
    32 #include "xmlsec_keyinfo.h"
       
    33 #include "xmlsec_soap.h"
       
    34 #include "xmlsec_xkms.h"
       
    35 #include "xmlsec_private.h"
       
    36 #include "xmlsec_privatexkms.h"
       
    37 #include "xmlsec_errors.h"
       
    38 
       
    39 #define XMLSEC_XKMS_ID_ATTRIBUTE_LEN		32
       
    40 
       
    41 /* The ID attribute in XKMS is 'Id' */
       
    42 static const xmlChar* xmlSecXkmsServerIds[] = { BAD_CAST "Id", NULL };
       
    43 
       
    44 #ifndef XMLSEC_NO_SOAP
       
    45 static int      xmlSecXkmsServerCtxWriteSoap11FatalError	(xmlSecXkmsServerCtxPtr ctx,
       
    46 							         xmlNodePtr envNode);
       
    47 static int      xmlSecXkmsServerCtxWriteSoap12FatalError	(xmlSecXkmsServerCtxPtr ctx,
       
    48 							         xmlNodePtr envNode);
       
    49 #endif /* XMLSEC_NO_SOAP */
       
    50 
       
    51 static int	xmlSecXkmsServerCtxRequestAbstractTypeNodeRead	(xmlSecXkmsServerCtxPtr ctx,
       
    52 							         xmlNodePtr* node);
       
    53 static int	xmlSecXkmsServerCtxSignatureNodeRead		(xmlSecXkmsServerCtxPtr ctx, 
       
    54 								 xmlNodePtr node);
       
    55 static int	xmlSecXkmsServerCtxMessageExtensionNodesRead	(xmlSecXkmsServerCtxPtr ctx, 
       
    56 								 xmlNodePtr* node);
       
    57 static int	xmlSecXkmsServerCtxOpaqueClientDataNodeRead	(xmlSecXkmsServerCtxPtr ctx, 
       
    58 								 xmlNodePtr node);
       
    59 static int	xmlSecXkmsServerCtxPendingNotificationNodeRead	(xmlSecXkmsServerCtxPtr ctx, 
       
    60 								 xmlNodePtr node);
       
    61 static int	xmlSecXkmsServerCtxRespondWithNodesRead		(xmlSecXkmsServerCtxPtr ctx, 
       
    62 								 xmlNodePtr* node);
       
    63 static int	xmlSecXkmsServerCtxPendingRequestNodeRead	(xmlSecXkmsServerCtxPtr ctx,
       
    64 							         xmlNodePtr* node);
       
    65 static int	xmlSecXkmsServerCtxQueryKeyBindingNodeRead	(xmlSecXkmsServerCtxPtr ctx,
       
    66 								 xmlNodePtr node);
       
    67 static int	xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead(xmlSecXkmsServerCtxPtr ctx,
       
    68 							         xmlNodePtr* node);
       
    69 static int	xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite(xmlSecXkmsServerCtxPtr ctx,
       
    70 							         xmlNodePtr node,
       
    71 								 xmlSecKeyPtr key);
       
    72 static int	xmlSecXkmsServerCtxKeyInfoNodeWrite		(xmlSecXkmsServerCtxPtr ctx,
       
    73 							    	 xmlNodePtr node,
       
    74 								 xmlSecKeyPtr key);
       
    75 static int	xmlSecXkmsServerCtxUseKeyWithNodesRead		(xmlSecXkmsServerCtxPtr ctx, 
       
    76 								 xmlNodePtr* node);
       
    77 static int	xmlSecXkmsServerCtxUseKeyWithNodesWrite		(xmlSecXkmsServerCtxPtr ctx, 
       
    78 								 xmlNodePtr node,
       
    79 								 xmlSecKeyPtr key);
       
    80 static int	xmlSecXkmsServerCtxTimeInstantNodeRead		(xmlSecXkmsServerCtxPtr ctx,
       
    81 								 xmlNodePtr node);
       
    82 static int	xmlSecXkmsServerCtxResultTypeNodeWrite		(xmlSecXkmsServerCtxPtr ctx, 
       
    83 								 xmlNodePtr node);
       
    84 static int	xmlSecXkmsServerCtxRequestSignatureValueNodeWrite(xmlSecXkmsServerCtxPtr ctx, 
       
    85 								 xmlNodePtr node);
       
    86 static int	xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(xmlSecXkmsServerCtxPtr ctx,
       
    87 							    	 xmlNodePtr node,
       
    88 								 xmlSecKeyPtr key);
       
    89 static int	xmlSecXkmsServerCtxKeyBindingNodeWrite		(xmlSecXkmsServerCtxPtr ctx,
       
    90 							    	 xmlNodePtr node,
       
    91 								 xmlSecKeyPtr key);
       
    92 static int 	xmlSecXkmsServerCtxValidityIntervalNodeWrite	(xmlSecXkmsServerCtxPtr ctx,
       
    93 								 xmlNodePtr node, 
       
    94 								 xmlSecKeyPtr key);
       
    95 static int	xmlSecXkmsServerCtxKeyBindingStatusNodeWrite	(xmlSecXkmsServerCtxPtr ctx,
       
    96 							    	 xmlNodePtr node,
       
    97 								 xmlSecKeyPtr key);
       
    98 
       
    99 
       
   100 static const xmlSecQName2IntegerInfo gXmlSecXkmsResultMajorInfo[] = 
       
   101 {
       
   102   { xmlSecXkmsNs, xmlSecResultMajorCodeSuccess,
       
   103     xmlSecXkmsResultMajorSuccess },
       
   104   { xmlSecXkmsNs, xmlSecResultMajorCodeVersionMismatch,
       
   105     xmlSecXkmsResultMajorVersionMismatch },
       
   106   { xmlSecXkmsNs, xmlSecResultMajorCodeSender, 
       
   107     xmlSecXkmsResultMajorSender },
       
   108   { xmlSecXkmsNs, xmlSecResultMajorCodeReceiver,
       
   109     xmlSecXkmsResultMajorReceiver },
       
   110   { xmlSecXkmsNs, xmlSecResultMajorCodeRepresent,     
       
   111     xmlSecXkmsResultMajorRepresent },
       
   112   { xmlSecXkmsNs, xmlSecResultMajorCodePending, 
       
   113     xmlSecXkmsResultMajorPending, },
       
   114   { NULL , NULL, 0 }	/* MUST be last in the list */
       
   115 };
       
   116 
       
   117 static const xmlSecQName2IntegerInfo gXmlSecXkmsMinorErrorInfo[] = 
       
   118 {
       
   119   { xmlSecXkmsNs, xmlSecResultMinorCodeNoMatch,
       
   120     xmlSecXkmsResultMinorNoMatch },
       
   121   { xmlSecXkmsNs, xmlSecResultMinorCodeTooManyResponses, 
       
   122     xmlSecXkmsResultMinorTooManyResponses },
       
   123   { xmlSecXkmsNs, xmlSecResultMinorCodeIncomplete,
       
   124     xmlSecXkmsResultMinorIncomplete },
       
   125   { xmlSecXkmsNs, xmlSecResultMinorCodeFailure, 
       
   126     xmlSecXkmsResultMinorFailure },
       
   127   { xmlSecXkmsNs, xmlSecResultMinorCodeRefused, 
       
   128     xmlSecXkmsResultMinorRefused },
       
   129   { xmlSecXkmsNs, xmlSecResultMinorCodeNoAuthentication, 
       
   130     xmlSecXkmsResultMinorNoAuthentication },
       
   131   { xmlSecXkmsNs, xmlSecResultMinorCodeMessageNotSupported, 
       
   132     xmlSecXkmsResultMinorMessageNotSupported },
       
   133   { xmlSecXkmsNs, xmlSecResultMinorCodeUnknownResponseId, 
       
   134     xmlSecXkmsResultMinorUnknownResponseId },
       
   135   { xmlSecXkmsNs, xmlSecResultMinorCodeNotSynchronous, 
       
   136     xmlSecXkmsResultMinorSynchronous },
       
   137   { NULL, NULL, 0 }	/* MUST be last in the list */
       
   138 };
       
   139 
       
   140 static const xmlSecQName2IntegerInfo gXmlSecXkmsKeyBindingStatusInfo[] = 
       
   141 {
       
   142   { xmlSecXkmsNs, xmlSecKeyBindingStatusValid, 
       
   143     xmlSecXkmsKeyBindingStatusValid },
       
   144   { xmlSecXkmsNs, xmlSecKeyBindingStatusInvalid,
       
   145     xmlSecXkmsKeyBindingStatusInvalid },
       
   146   { xmlSecXkmsNs, xmlSecKeyBindingStatusIndeterminate, 
       
   147     xmlSecXkmsKeyBindingStatusIndeterminate },
       
   148   { NULL, NULL, 0 }	/* MUST be last in the list */
       
   149 };
       
   150 
       
   151 static const xmlSecQName2BitMaskInfo gXmlSecXkmsKeyUsageInfo[] = 
       
   152 {
       
   153   { xmlSecXkmsNs, xmlSecKeyUsageEncryption,
       
   154     xmlSecKeyUsageEncrypt | xmlSecKeyUsageDecrypt },
       
   155   { xmlSecXkmsNs, xmlSecKeyUsageSignature,
       
   156     xmlSecKeyUsageSign | xmlSecKeyUsageVerify },
       
   157   { xmlSecXkmsNs, xmlSecKeyUsageExchange,
       
   158     xmlSecKeyUsageKeyExchange},
       
   159   { NULL, NULL, 0 }	/* MUST be last in the list */
       
   160 };
       
   161 
       
   162 static const xmlSecQName2BitMaskInfo gXmlSecXkmsKeyBindingReasonInfo[] = 
       
   163 {
       
   164     { xmlSecXkmsNs, xmlSecKeyBindingReasonIssuerTrust,
       
   165       XMLSEC_XKMS_KEY_BINDING_REASON_MASK_ISSUER_TRAST },
       
   166     { xmlSecXkmsNs, xmlSecKeyBindingReasonRevocationStatus,
       
   167       XMLSEC_XKMS_KEY_BINDING_REASON_MASK_REVOCATION_STATUS },
       
   168     { xmlSecXkmsNs, xmlSecKeyBindingReasonValidityInterval,
       
   169       XMLSEC_XKMS_KEY_BINDING_REASON_MASK_VALIDITY_INTERVAL },
       
   170     { xmlSecXkmsNs, xmlSecKeyBindingReasonSignature,
       
   171       XMLSEC_XKMS_KEY_BINDING_REASON_MASK_SIGNATURE },
       
   172     { NULL, NULL, 0 }	/* MUST be last in the list */
       
   173 };
       
   174 
       
   175 static const xmlSecQName2BitMaskInfo gXmlSecXkmsResponseMechanismInfo[] = 
       
   176 {
       
   177     { xmlSecXkmsNs, xmlSecResponseMechanismRepresent,
       
   178       XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_REPRESENT },
       
   179     { xmlSecXkmsNs, xmlSecResponseMechanismPending,
       
   180       XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_PENDING },
       
   181     { xmlSecXkmsNs, xmlSecResponseMechanismRequestSignatureValue,
       
   182       XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_REQUEST_SIGNATURE_VALUE },
       
   183     { NULL, NULL, 0 }	/* MUST be last in the list */
       
   184 };
       
   185 
       
   186 static const xmlSecQName2IntegerInfo gXmlSecXkmsFormatInfo[] = 
       
   187 {
       
   188   { NULL, xmlSecXkmsFormatStrPlain, 
       
   189     xmlSecXkmsServerFormatPlain },
       
   190 #ifndef XMLSEC_NO_SOAP
       
   191   { NULL, xmlSecXkmsFormatStrSoap11,
       
   192     xmlSecXkmsServerFormatSoap11 },
       
   193   { NULL, xmlSecXkmsFormatStrSoap12, 
       
   194     xmlSecXkmsServerFormatSoap12 },
       
   195 #endif /* XMLSEC_NO_SOAP */
       
   196   { NULL, NULL, 0 }	/* MUST be last in the list */
       
   197 };
       
   198 
       
   199 /**
       
   200  * xmlSecXkmsServerFormatFromString:
       
   201  * @str         the string.
       
   202  *  
       
   203  * Gets xmlSecXkmsServerFormat from string @str.
       
   204  * 
       
   205  * Returns corresponding format or xmlSecXkmsServerFormatUnknown
       
   206  * if format could not be recognized.
       
   207  */
       
   208 EXPORT_C 
       
   209 xmlSecXkmsServerFormat 
       
   210 xmlSecXkmsServerFormatFromString(const xmlChar* str) {
       
   211     int res;
       
   212     int ret;
       
   213 
       
   214     xmlSecAssert2(str != NULL, xmlSecXkmsServerFormatUnknown);
       
   215     
       
   216     ret = xmlSecQName2IntegerGetInteger(gXmlSecXkmsFormatInfo, NULL, str, &res);
       
   217     if(ret < 0) {
       
   218 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   219 		    NULL,
       
   220 		    "xmlSecQName2IntegerGetInteger",
       
   221 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   222 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   223 	return(xmlSecXkmsServerFormatUnknown);   
       
   224     }
       
   225 
       
   226     return((xmlSecXkmsServerFormat)res);
       
   227 }
       
   228 
       
   229 /**
       
   230  * xmlSecXkmsServerFormatToString:
       
   231  * @format:     the format.
       
   232  *
       
   233  * Gets string from @format.
       
   234  *
       
   235  * Returns string corresponding to @format or NULL if an error occurs.
       
   236  */
       
   237 EXPORT_C
       
   238 const xmlChar* 
       
   239 xmlSecXkmsServerFormatToString (xmlSecXkmsServerFormat format) {
       
   240     xmlSecQName2IntegerInfoConstPtr info;
       
   241     
       
   242     xmlSecAssert2(format != xmlSecXkmsServerFormatUnknown, NULL);
       
   243 
       
   244     info = xmlSecQName2IntegerGetInfo(gXmlSecXkmsFormatInfo, format);
       
   245     if(info == NULL) {
       
   246 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   247 		    NULL,
       
   248 		    "xmlSecQName2IntegerGetInfo",
       
   249 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   250 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   251         return(NULL);
       
   252     }
       
   253     return(info->qnameLocalPart);
       
   254 }
       
   255 
       
   256 /**
       
   257  * xmlSecXkmsServerCtxCreate:
       
   258  * @keysMngr: 	the pointer to keys manager.
       
   259  *
       
   260  * Creates XKMS request server side processing context.
       
   261  * The caller is responsible for destroying returend object by calling 
       
   262  * #xmlSecXkmsServerCtxDestroy function.
       
   263  *
       
   264  * Returns pointer to newly allocated context object or NULL if an error
       
   265  * occurs.
       
   266  */
       
   267 EXPORT_C
       
   268 xmlSecXkmsServerCtxPtr	
       
   269 xmlSecXkmsServerCtxCreate(xmlSecKeysMngrPtr keysMngr) {
       
   270     xmlSecXkmsServerCtxPtr ctx;
       
   271     int ret;
       
   272     
       
   273     ctx = (xmlSecXkmsServerCtxPtr) xmlMalloc(sizeof(xmlSecXkmsServerCtx));
       
   274     if(ctx == NULL) {
       
   275 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   276 		    NULL,
       
   277 		    NULL,
       
   278 		    XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   279 		    "sizeof(xmlSecXkmsServerCtx)=%d", 
       
   280 		    sizeof(xmlSecXkmsServerCtx));
       
   281 	return(NULL);
       
   282     }
       
   283     
       
   284     ret = xmlSecXkmsServerCtxInitialize(ctx, keysMngr);
       
   285     if(ret < 0) {
       
   286 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   287 		    NULL,
       
   288 		    "xmlSecXkmsServerCtxInitialize",
       
   289 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   290 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   291 	xmlSecXkmsServerCtxDestroy(ctx);
       
   292 	return(NULL);   
       
   293     }
       
   294     return(ctx);    
       
   295 }
       
   296 
       
   297 /**
       
   298  * xmlSecXkmsServerCtxDestroy:
       
   299  * @ctx:	the pointer to XKMS processing context.
       
   300  *
       
   301  * Destroy context object created with #xmlSecXkmsServerCtxCreate function.
       
   302  */
       
   303 EXPORT_C
       
   304 void  
       
   305 xmlSecXkmsServerCtxDestroy(xmlSecXkmsServerCtxPtr ctx) {
       
   306     xmlSecAssert(ctx != NULL);
       
   307     
       
   308     xmlSecXkmsServerCtxFinalize(ctx);
       
   309     xmlFree(ctx);
       
   310 }
       
   311 
       
   312 /**
       
   313  * xmlSecXkmsServerCtxInitialize:
       
   314  * @ctx:	the pointer to XKMS processing context.
       
   315  * @keysMngr: 	the pointer to keys manager.
       
   316  *
       
   317  * Initializes XKMS element processing context.
       
   318  * The caller is responsible for cleaing up returend object by calling 
       
   319  * #xmlSecXkmsServerCtxFinalize function.
       
   320  *
       
   321  * Returns 0 on success or a negative value if an error occurs.
       
   322  */
       
   323 EXPORT_C
       
   324 int 
       
   325 xmlSecXkmsServerCtxInitialize(xmlSecXkmsServerCtxPtr ctx, xmlSecKeysMngrPtr keysMngr) {
       
   326     int ret;
       
   327     
       
   328     xmlSecAssert2(ctx != NULL, -1);
       
   329     
       
   330     memset(ctx, 0, sizeof(xmlSecXkmsServerCtx));
       
   331 
       
   332     ctx->resultMajor 	= xmlSecXkmsResultMajorSuccess;
       
   333     ctx->resultMinor 	= xmlSecXkmsResultMinorNone;
       
   334     ctx->responseLimit  = XMLSEC_XKMS_NO_RESPONSE_LIMIT;
       
   335     ctx->idLen		= XMLSEC_XKMS_ID_ATTRIBUTE_LEN;
       
   336 
       
   337     /* initialize key info */
       
   338     ret = xmlSecKeyInfoCtxInitialize(&(ctx->keyInfoReadCtx), keysMngr);
       
   339     if(ret < 0) {
       
   340 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   341 		    NULL,
       
   342 		    "xmlSecKeyInfoCtxInitialize",
       
   343 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   344 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   345 	return(-1);   
       
   346     }
       
   347     ctx->keyInfoReadCtx.mode = xmlSecKeyInfoModeRead;
       
   348     
       
   349     ret = xmlSecKeyInfoCtxInitialize(&(ctx->keyInfoWriteCtx), keysMngr);
       
   350     if(ret < 0) {
       
   351 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   352 		    NULL,
       
   353 		    "xmlSecKeyInfoCtxInitialize",
       
   354 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   355 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   356 	return(-1);   
       
   357     }
       
   358     ctx->keyInfoWriteCtx.mode = xmlSecKeyInfoModeWrite;
       
   359 
       
   360     /* enabled RespondWith */
       
   361     ret = xmlSecPtrListInitialize(&(ctx->enabledRespondWithIds), xmlSecXkmsRespondWithIdListId);
       
   362     if(ret < 0) { 
       
   363 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   364 		    NULL,
       
   365 		    "xmlSecPtrListInitialize",
       
   366 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   367 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   368 	return(-1);
       
   369     }
       
   370 
       
   371     /* enabled ServerRequest */
       
   372     ret = xmlSecPtrListInitialize(&(ctx->enabledServerRequestIds), xmlSecXkmsServerRequestIdListId);
       
   373     if(ret < 0) { 
       
   374 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   375 		    NULL,
       
   376 		    "xmlSecPtrListInitialize",
       
   377 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   378 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   379 	return(-1);
       
   380     }
       
   381 
       
   382 
       
   383 
       
   384     /* initialize keys list */
       
   385     ret = xmlSecPtrListInitialize(&(ctx->keys), xmlSecKeyPtrListId);
       
   386     if(ret < 0) {
       
   387 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   388 		    NULL,
       
   389 		    "xmlSecPtrListInitialize",
       
   390 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   391 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   392 	return(-1);   
       
   393     }
       
   394 
       
   395     /* initialize RespondWith list */
       
   396     ret = xmlSecPtrListInitialize(&(ctx->respWithList), xmlSecXkmsRespondWithIdListId);
       
   397     if(ret < 0) {
       
   398 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   399 		    NULL,
       
   400 		    "xmlSecPtrListInitialize",
       
   401 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   402 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   403 	return(-1);   
       
   404     }
       
   405 
       
   406     return(0);
       
   407 }
       
   408 
       
   409 /**
       
   410  * xmlSecXkmsServerCtxFinalize:
       
   411  * @ctx:	the pointer to XKMS processing context.
       
   412  *
       
   413  * Cleans up @ctx object.
       
   414  */
       
   415 EXPORT_C
       
   416 void 
       
   417 xmlSecXkmsServerCtxFinalize(xmlSecXkmsServerCtxPtr ctx) {
       
   418     xmlSecAssert(ctx != NULL);
       
   419 
       
   420     xmlSecXkmsServerCtxReset(ctx);
       
   421     
       
   422     if(ctx->expectedService != NULL) {
       
   423 	xmlFree(ctx->expectedService);
       
   424     }
       
   425     if(ctx->idPrefix != NULL) {
       
   426 	xmlFree(ctx->idPrefix);
       
   427     }
       
   428 
       
   429     xmlSecKeyInfoCtxFinalize(&(ctx->keyInfoReadCtx));
       
   430     xmlSecKeyInfoCtxFinalize(&(ctx->keyInfoWriteCtx));
       
   431     xmlSecPtrListFinalize(&(ctx->enabledRespondWithIds));
       
   432     xmlSecPtrListFinalize(&(ctx->enabledServerRequestIds));
       
   433     xmlSecPtrListFinalize(&(ctx->keys));
       
   434     xmlSecPtrListFinalize(&(ctx->respWithList));
       
   435     memset(ctx, 0, sizeof(xmlSecXkmsServerCtx));
       
   436 }
       
   437 
       
   438 /**
       
   439  * xmlSecXkmsServerCtxReset:
       
   440  * @ctx:	the pointer to XKMS processing context.
       
   441  *
       
   442  * Resets @ctx object, user settings are not touched.
       
   443  */
       
   444 EXPORT_C
       
   445 void 
       
   446 xmlSecXkmsServerCtxReset(xmlSecXkmsServerCtxPtr ctx) {
       
   447     xmlSecAssert(ctx != NULL);
       
   448     
       
   449     ctx->resultMajor = xmlSecXkmsResultMajorSuccess;
       
   450     ctx->resultMinor = xmlSecXkmsResultMinorNone;
       
   451     xmlSecKeyInfoCtxReset(&(ctx->keyInfoReadCtx));
       
   452     xmlSecKeyInfoCtxReset(&(ctx->keyInfoWriteCtx));
       
   453     xmlSecPtrListEmpty(&(ctx->keys));
       
   454     xmlSecPtrListEmpty(&(ctx->respWithList));
       
   455 
       
   456     ctx->requestNode            = NULL;    
       
   457     ctx->opaqueClientDataNode   = NULL;    
       
   458     ctx->firtsMsgExtNode 	= NULL;
       
   459     ctx->keyInfoNode		= NULL;
       
   460     ctx->requestId		= xmlSecXkmsServerRequestIdUnknown;
       
   461     
       
   462     if(ctx->id != NULL) {
       
   463 	xmlFree(ctx->id); ctx->id = NULL;
       
   464     }
       
   465     if(ctx->service != NULL) {
       
   466 	xmlFree(ctx->service); ctx->service = NULL;
       
   467     }
       
   468     if(ctx->nonce != NULL) {
       
   469 	xmlFree(ctx->nonce); ctx->nonce = NULL;
       
   470     }
       
   471     if(ctx->originalRequestId != NULL) {
       
   472 	xmlFree(ctx->originalRequestId); ctx->originalRequestId = NULL;
       
   473     }
       
   474     if(ctx->pendingNotificationMechanism != NULL) {
       
   475 	xmlFree(ctx->pendingNotificationMechanism); 
       
   476 	ctx->pendingNotificationMechanism = NULL;
       
   477     }
       
   478     if(ctx->pendingNotificationIdentifier != NULL) {
       
   479 	xmlFree(ctx->pendingNotificationIdentifier); 
       
   480 	ctx->pendingNotificationIdentifier = NULL;
       
   481     }
       
   482     if(ctx->compoundRequestContexts != NULL) {
       
   483         xmlSecPtrListDestroy(ctx->compoundRequestContexts);
       
   484         ctx->compoundRequestContexts = NULL;
       
   485     }
       
   486     
       
   487     ctx->responseLimit 		= XMLSEC_XKMS_NO_RESPONSE_LIMIT;
       
   488     ctx->responseMechanismMask  = 0;
       
   489 }
       
   490 
       
   491 /**
       
   492  * xmlSecXkmsServerCtxCopyUserPref:
       
   493  * @dst:	the pointer to destination context.
       
   494  * @src:	the pointer to source context.
       
   495  * 
       
   496  * Copies user preference from @src context to @dst.
       
   497  *
       
   498  * Returns 0 on success or a negative value if an error occurs.
       
   499  */
       
   500 EXPORT_C
       
   501 int 
       
   502 xmlSecXkmsServerCtxCopyUserPref(xmlSecXkmsServerCtxPtr dst, xmlSecXkmsServerCtxPtr src) {
       
   503     int ret;
       
   504     
       
   505     xmlSecAssert2(dst != NULL, -1);
       
   506     xmlSecAssert2(src != NULL, -1);
       
   507 
       
   508     dst->userData 	= src->userData;
       
   509     dst->flags		= src->flags;
       
   510     dst->flags2		= src->flags2;
       
   511 
       
   512     ret = xmlSecKeyInfoCtxCopyUserPref(&(dst->keyInfoReadCtx), &(src->keyInfoReadCtx));
       
   513     if(ret < 0) {
       
   514     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   515 		    NULL,
       
   516 		    "xmlSecKeyInfoCtxCopyUserPref",
       
   517 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   518 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   519 	return(-1);
       
   520     }
       
   521 
       
   522     ret = xmlSecKeyInfoCtxCopyUserPref(&(dst->keyInfoWriteCtx), &(src->keyInfoWriteCtx));
       
   523     if(ret < 0) {
       
   524     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   525 		    NULL,
       
   526 		    "xmlSecKeyInfoCtxCopyUserPref",
       
   527 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   528 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   529 	return(-1);
       
   530     }
       
   531     
       
   532     if(src->expectedService != NULL) {
       
   533 	dst->expectedService = xmlStrdup(src->expectedService);
       
   534 	if(dst->expectedService == NULL) {
       
   535 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   536 			NULL,
       
   537 			"xmlStrdup",
       
   538 		        XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   539 			XMLSEC_ERRORS_NO_MESSAGE);
       
   540 	    return(-1);
       
   541 	}
       
   542     }
       
   543 
       
   544     if(src->idPrefix != NULL) {
       
   545 	dst->idPrefix = xmlStrdup(src->idPrefix);
       
   546 	if(dst->idPrefix == NULL) {
       
   547 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   548 			NULL,
       
   549 			"xmlStrdup",
       
   550 		        XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   551 			XMLSEC_ERRORS_NO_MESSAGE);
       
   552 	    return(-1);
       
   553 	}
       
   554     }
       
   555     src->idLen = dst->idLen;
       
   556 
       
   557 
       
   558     ret = xmlSecPtrListCopy(&(dst->enabledRespondWithIds), &(src->enabledRespondWithIds));
       
   559     if(ret < 0) { 
       
   560 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   561 		    NULL,
       
   562 		    "xmlSecPtrListCopy",
       
   563 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   564 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   565 	return(-1);
       
   566     }
       
   567 
       
   568     ret = xmlSecPtrListCopy(&(dst->enabledServerRequestIds), &(src->enabledServerRequestIds));
       
   569     if(ret < 0) { 
       
   570 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   571 		    NULL,
       
   572 		    "xmlSecPtrListCopy",
       
   573 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   574 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   575 	return(-1);
       
   576     }
       
   577 
       
   578     return(0);
       
   579 } 
       
   580 
       
   581 /** 
       
   582  * xmlSecXkmsServerCtxProcess: 
       
   583  * @ctx:	the pointer to XKMS processing context.
       
   584  * @node:	the pointer to request node.
       
   585  * @format:     the request/response format.
       
   586  * @doc:	the pointer to response parent XML document (might be NULL).
       
   587  * 
       
   588  * Reads XKMS request from @node and creates response to a newly created node. 
       
   589  * Caller is responsible for adding the returned node to the XML document.
       
   590  *
       
   591  * Returns pointer to newly created XKMS response node or NULL
       
   592  * if an error occurs.
       
   593  */
       
   594 EXPORT_C
       
   595 xmlNodePtr 
       
   596 xmlSecXkmsServerCtxProcess(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, 
       
   597                               xmlSecXkmsServerFormat format, xmlDocPtr doc) {
       
   598     int ret;
       
   599 
       
   600     xmlSecAssert2(ctx != NULL, NULL);
       
   601     xmlSecAssert2(ctx->requestId == NULL, NULL);
       
   602     xmlSecAssert2(ctx->requestNode == NULL, NULL);
       
   603     xmlSecAssert2(node != NULL, NULL);
       
   604 
       
   605     ctx->requestNode = xmlSecXkmsServerCtxRequestUnwrap(ctx, node, format);
       
   606     if(ctx->requestNode == NULL) {
       
   607     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   608 		    NULL,
       
   609 		    "xmlSecXkmsServerCtxRequestUnwrap",
       
   610 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   611 		    "node=%s",
       
   612 		    xmlSecErrorsSafeString(node->name));
       
   613 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   614 	goto done;
       
   615     }    
       
   616         
       
   617     ret = xmlSecXkmsServerCtxRequestRead(ctx, ctx->requestNode);
       
   618     if(ret < 0) {
       
   619     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   620 		    NULL,
       
   621 		    "xmlSecXkmsServerRequestIdListFindByNode",
       
   622 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   623 		    "ctx->requestNode=%s",
       
   624 		    xmlSecErrorsSafeString(ctx->requestNode->name));
       
   625 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   626 	goto done;
       
   627     }    
       
   628 
       
   629     ret = xmlSecXkmsServerRequestExecute(ctx->requestId, ctx);
       
   630     if(ret < 0) {
       
   631     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   632 		    NULL,
       
   633 		    "xmlSecXkmsServerRequestExecute",
       
   634 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   635 		    "ctx->requestNode=%s",
       
   636 		    xmlSecErrorsSafeString(ctx->requestNode->name));
       
   637 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   638 	goto done;
       
   639     }
       
   640 
       
   641 done:
       
   642     /* always try to write response back */    
       
   643     if(ctx->requestId != NULL) {
       
   644         xmlNodePtr respNode;
       
   645         xmlNodePtr wrappedRespNode;
       
   646         
       
   647         respNode = xmlSecXkmsServerCtxResponseWrite(ctx, doc);
       
   648         if(respNode == NULL) {
       
   649     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   650 		        NULL,
       
   651 		        "xmlSecXkmsServerCtxResponseWrite",
       
   652 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   653 		        "ctx->requestNode=%s",
       
   654 		        xmlSecErrorsSafeString(ctx->requestNode->name));
       
   655 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   656             goto error;    
       
   657         }
       
   658     
       
   659 
       
   660         wrappedRespNode = xmlSecXkmsServerCtxResponseWrap(ctx, respNode, format, doc);
       
   661         if(wrappedRespNode == NULL) {
       
   662     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   663 		        NULL,
       
   664 		        "xmlSecXkmsServerCtxResponseWrite",
       
   665 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   666 		        "ctx->requestNode=%s",
       
   667 		        xmlSecErrorsSafeString(ctx->requestNode->name));
       
   668 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   669             xmlFreeNode(respNode);
       
   670             goto error;    
       
   671         }
       
   672 
       
   673         return(wrappedRespNode);
       
   674     }
       
   675     
       
   676 error:
       
   677     /* last attempt: create fatatl error response */
       
   678     return(xmlSecXkmsServerCtxFatalErrorResponseCreate(ctx, format, doc));
       
   679 }
       
   680 
       
   681 /** 
       
   682  * xmlSecXkmsServerCtxRequestRead: 
       
   683  * @ctx:	the pointer to XKMS processing context.
       
   684  * @node:	the pointer to request node.
       
   685  *
       
   686  * Reads XKMS request from @node and stores data in @ctx.
       
   687  *
       
   688  * Returns 0 on success or a negative value if an error occurs.
       
   689  */
       
   690 EXPORT_C
       
   691 int 
       
   692 xmlSecXkmsServerCtxRequestRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
   693     int ret;
       
   694     
       
   695     xmlSecAssert2(ctx != NULL, -1);
       
   696     xmlSecAssert2(ctx->requestId == NULL, -1);
       
   697     xmlSecAssert2(node != NULL, -1);
       
   698 
       
   699     /* find out what the request is */
       
   700     if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
       
   701 	ctx->requestId = xmlSecXkmsServerRequestIdListFindByNode(&(ctx->enabledServerRequestIds), node);
       
   702     } else {
       
   703 	ctx->requestId = xmlSecXkmsServerRequestIdListFindByNode(xmlSecXkmsServerRequestIdsGet(), node);
       
   704     }
       
   705     if(ctx->requestId == xmlSecXkmsServerRequestIdUnknown) {
       
   706     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   707 		    NULL,
       
   708 		    "xmlSecXkmsServerRequestIdListFindByNode",
       
   709 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   710 		    "node=%s",
       
   711 		    xmlSecErrorsSafeString(node->name));
       
   712 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorMessageNotSupported);
       
   713 	return(-1);
       
   714     }
       
   715 
       
   716     xmlSecAddIDs(node->doc, node, xmlSecXkmsServerIds);
       
   717     ret = xmlSecXkmsServerRequestNodeRead(ctx->requestId, ctx, node);
       
   718     if(ret < 0) {
       
   719     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   720 		    NULL,
       
   721 		    "xmlSecXkmsServerRequestNodeRead",
       
   722 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   723 		    "request=%s",
       
   724 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctx->requestId)));
       
   725 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   726 	return(-1);
       
   727     }
       
   728         
       
   729     return(0);
       
   730 }
       
   731 
       
   732 /** 
       
   733  * xmlSecXkmsServerCtxResponseWrite: 
       
   734  * @ctx:	the pointer to XKMS processing context.
       
   735  * @doc:	the pointer to response parent XML document (might be NULL).
       
   736  *
       
   737  * Writes XKMS response from context to a newly created node. Caller is 
       
   738  * responsible for adding the returned node to the XML document.
       
   739  *
       
   740  * Returns pointer to newly created XKMS response node or NULL
       
   741  * if an error occurs.
       
   742  */
       
   743 EXPORT_C
       
   744 xmlNodePtr
       
   745 xmlSecXkmsServerCtxResponseWrite(xmlSecXkmsServerCtxPtr ctx, xmlDocPtr doc) {
       
   746     xmlNodePtr respNode;
       
   747     
       
   748     xmlSecAssert2(ctx != NULL, NULL);
       
   749     xmlSecAssert2(ctx->requestId != NULL, NULL);
       
   750 
       
   751     /* now write results */
       
   752     respNode = xmlSecXkmsServerRequestNodeWrite(ctx->requestId, ctx, doc, NULL);
       
   753     if(respNode == NULL) {
       
   754     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   755 		    NULL,
       
   756 		    "xmlSecXkmsServerRequestNodeWrite",
       
   757 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   758 		    "request=%s",
       
   759 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctx->requestId)));
       
   760 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   761         return(NULL);
       
   762     }
       
   763     
       
   764     return(respNode);
       
   765 }
       
   766 
       
   767 /**
       
   768  * xmlSecXkmsServerCtxRequestUnwrap:
       
   769  * @ctx:	the pointer to XKMS processing context.
       
   770  * @node:	the pointer to request node.
       
   771  * @format:     the request/response format.
       
   772  * 
       
   773  * Removes SOAP or other envelope from XKMS request.
       
   774  *
       
   775  * Returns pointer to "real" XKMS request node or NULL if an error occurs. 
       
   776  */
       
   777 EXPORT_C
       
   778 xmlNodePtr 
       
   779 xmlSecXkmsServerCtxRequestUnwrap(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node,  xmlSecXkmsServerFormat format) {
       
   780     xmlNodePtr result = NULL;
       
   781         
       
   782     xmlSecAssert2(ctx != NULL, NULL);
       
   783     xmlSecAssert2(node != NULL, NULL);
       
   784     
       
   785     switch(format) {
       
   786     case xmlSecXkmsServerFormatPlain:
       
   787         result = node;
       
   788         break;
       
   789 #ifndef XMLSEC_NO_SOAP
       
   790     case xmlSecXkmsServerFormatSoap11:
       
   791         /* verify that it is actually soap Envelope node */
       
   792         if(xmlSecSoap11CheckEnvelope(node) != 1) {
       
   793             xmlSecError(XMLSEC_ERRORS_HERE,
       
   794 		        NULL,
       
   795 		        "xmlSecSoap11CheckEnvelope",
       
   796 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   797 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   798 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   799 	    return(NULL);
       
   800         }   
       
   801         
       
   802         /* check that Body has exactly one entry */
       
   803         if(xmlSecSoap11GetBodyEntriesNumber(node) != 1) {
       
   804             xmlSecError(XMLSEC_ERRORS_HERE,
       
   805 		        NULL,
       
   806 		        "xmlSecSoap11GetBodyEntriesNumber",
       
   807 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   808 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   809 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   810 	    return(NULL);
       
   811         }
       
   812         
       
   813         /* this one enntry is our xkms request */
       
   814         result = xmlSecSoap11GetBodyEntry(node, 0);
       
   815         if(result == NULL) {
       
   816             xmlSecError(XMLSEC_ERRORS_HERE,
       
   817 		        NULL,
       
   818 		        "xmlSecSoap11GetBodyEntry",
       
   819 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   820 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   821 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   822 	    return(NULL);
       
   823         }
       
   824         
       
   825         break;
       
   826     case xmlSecXkmsServerFormatSoap12:
       
   827         /* verify that it is actually soap Envelope node */
       
   828         if(xmlSecSoap12CheckEnvelope(node) != 1) {
       
   829             xmlSecError(XMLSEC_ERRORS_HERE,
       
   830 		        NULL,
       
   831 		        "xmlSecSoap12CheckEnvelope",
       
   832 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   833 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   834 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   835 	    return(NULL);
       
   836         }   
       
   837         
       
   838         /* check that Body has exactly one entry */
       
   839         if(xmlSecSoap12GetBodyEntriesNumber(node) != 1) {
       
   840             xmlSecError(XMLSEC_ERRORS_HERE,
       
   841 		        NULL,
       
   842 		        "xmlSecSoap12GetBodyEntriesNumber",
       
   843 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   844 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   845 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   846 	    return(NULL);
       
   847         }
       
   848         
       
   849         /* this one enntry is our xkms request */
       
   850         result = xmlSecSoap12GetBodyEntry(node, 0);
       
   851         if(result == NULL) {
       
   852             xmlSecError(XMLSEC_ERRORS_HERE,
       
   853 		        NULL,
       
   854 		        "xmlSecSoap12GetBodyEntry",
       
   855 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   856 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   857 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   858 	    return(NULL);
       
   859         }
       
   860         
       
   861         break;
       
   862 #endif /* XMLSEC_NO_SOAP */
       
   863     default:
       
   864     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   865 		    NULL,
       
   866 		    NULL,
       
   867 		    XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
       
   868 		    "format=%d",
       
   869                     format);
       
   870 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   871 	return(NULL);
       
   872     }
       
   873     
       
   874     return(result);
       
   875 }
       
   876 
       
   877 /** 
       
   878  * xmlSecXkmsServerCtxResponseWrap: 
       
   879  * @ctx:	the pointer to XKMS processing context.
       
   880  * @node:	the pointer to response node.
       
   881  * @format:     the request/response format.
       
   882  * @doc:	the pointer to response parent XML document (might be NULL).
       
   883  *
       
   884  * Creates SOAP or other envelope around XKMS response.
       
   885  * Caller is responsible for adding the returned node to the XML document.
       
   886  *
       
   887  * Returns pointer to newly created response envelope node or NULL
       
   888  * if an error occurs.
       
   889  */
       
   890 EXPORT_C
       
   891 xmlNodePtr 
       
   892 xmlSecXkmsServerCtxResponseWrap(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecXkmsServerFormat format, xmlDocPtr doc) {
       
   893     xmlNodePtr result = NULL;
       
   894     
       
   895     xmlSecAssert2(ctx != NULL, NULL);
       
   896     xmlSecAssert2(node != NULL, NULL);
       
   897     
       
   898     switch(format) {
       
   899     case xmlSecXkmsServerFormatPlain:
       
   900         result = node; /* do nothing */
       
   901         break;
       
   902 #ifndef XMLSEC_NO_SOAP
       
   903     case xmlSecXkmsServerFormatSoap11:
       
   904         result = xmlSecSoap11CreateEnvelope(doc);
       
   905         if(result == NULL) {
       
   906             xmlSecError(XMLSEC_ERRORS_HERE,
       
   907 		        NULL,
       
   908 		        "xmlSecSoap11CreateEnvelope",
       
   909 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   910 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   911 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   912 	    return(NULL);
       
   913         }
       
   914         
       
   915         if(xmlSecSoap11AddBodyEntry(result, node) == NULL) {
       
   916             xmlSecError(XMLSEC_ERRORS_HERE,
       
   917 		        NULL,
       
   918 		        "xmlSecSoap11AddBodyEntry",
       
   919 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   920 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   921 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   922 	    return(NULL);
       
   923         }
       
   924         break;
       
   925     case xmlSecXkmsServerFormatSoap12:
       
   926         result = xmlSecSoap12CreateEnvelope(doc);
       
   927         if(result == NULL) {
       
   928             xmlSecError(XMLSEC_ERRORS_HERE,
       
   929 		        NULL,
       
   930 		        "xmlSecSoap12CreateEnvelope",
       
   931 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   932 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   933 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   934 	    return(NULL);
       
   935         }
       
   936         
       
   937         if(xmlSecSoap12AddBodyEntry(result, node) == NULL) {
       
   938             xmlSecError(XMLSEC_ERRORS_HERE,
       
   939 		        NULL,
       
   940 		        "xmlSecSoap12AddBodyEntry",
       
   941 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
   942 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   943 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   944 	    return(NULL);
       
   945         }
       
   946         break;
       
   947 #endif /* XMLSEC_NO_SOAP */
       
   948     default:
       
   949     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   950 		    NULL,
       
   951 		    NULL,
       
   952 		    XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
       
   953 		    "format=%d",
       
   954                     format);
       
   955 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
   956 	return(NULL);
       
   957     }
       
   958     
       
   959     return(result);
       
   960 }
       
   961 
       
   962 /** 
       
   963  * xmlSecXkmsServerCtxFatalErrorResponseCreate: 
       
   964  * @ctx:	the pointer to XKMS processing context.
       
   965  * @format:     the request/response format.
       
   966  * @doc:	the pointer to response parent XML document (might be NULL).
       
   967  *
       
   968  * Creates a "fatal error" SOAP or other envelope respons. Caller is 
       
   969  * responsible for adding the returned node to the XML document.
       
   970  *
       
   971  * Returns pointer to newly created fatal error response (it might be NULL).
       
   972  */
       
   973 EXPORT_C
       
   974 xmlNodePtr 
       
   975 xmlSecXkmsServerCtxFatalErrorResponseCreate(xmlSecXkmsServerCtxPtr ctx, xmlSecXkmsServerFormat format, xmlDocPtr doc) {
       
   976     xmlNodePtr result = NULL;
       
   977     int ret;
       
   978     
       
   979     xmlSecAssert2(ctx != NULL, NULL);
       
   980 
       
   981     /* make sure that we have an error */
       
   982     if(ctx->resultMajor == xmlSecXkmsResultMajorSuccess) {
       
   983 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
   984     }
       
   985     
       
   986     switch(format) {
       
   987     case xmlSecXkmsServerFormatPlain:
       
   988         /* try to create fatal error response with XKMS Status request */
       
   989         result = xmlSecXkmsServerRequestNodeWrite(xmlSecXkmsServerRequestResultId, ctx, doc, NULL);
       
   990         if(result == NULL) {
       
   991             xmlSecError(XMLSEC_ERRORS_HERE,
       
   992 		        NULL,
       
   993 		        "xmlSecXkmsServerRequestNodeWrite",
       
   994 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   995 		        XMLSEC_ERRORS_NO_MESSAGE);
       
   996 	    return(NULL);
       
   997         }
       
   998         break;
       
   999 #ifndef XMLSEC_NO_SOAP
       
  1000     case xmlSecXkmsServerFormatSoap11:
       
  1001         result = xmlSecSoap11CreateEnvelope(doc);
       
  1002         if(result == NULL) {
       
  1003             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1004 		        NULL,
       
  1005 		        "xmlSecSoap11CreateEnvelope",
       
  1006 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
  1007 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1008 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1009 	    return(NULL);
       
  1010         }
       
  1011         
       
  1012         ret = xmlSecXkmsServerCtxWriteSoap11FatalError(ctx, result);
       
  1013         if(ret < 0) {
       
  1014             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1015 		        NULL,
       
  1016 		        "xmlSecXkmsServerCtxWriteSoap11FatalError",
       
  1017 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
  1018 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1019 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1020             xmlFreeNode(result);
       
  1021 	    return(NULL);
       
  1022         }
       
  1023                 
       
  1024         break;
       
  1025     case xmlSecXkmsServerFormatSoap12:
       
  1026         result = xmlSecSoap12CreateEnvelope(doc);
       
  1027         if(result == NULL) {
       
  1028             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1029 		        NULL,
       
  1030 		        "xmlSecSoap12CreateEnvelope",
       
  1031 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
  1032 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1033 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1034 	    return(NULL);
       
  1035         }
       
  1036         
       
  1037         ret = xmlSecXkmsServerCtxWriteSoap12FatalError(ctx, result);
       
  1038         if(ret < 0) {
       
  1039             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1040 		        NULL,
       
  1041 		        "xmlSecXkmsServerCtxWriteSoap12FatalError",
       
  1042 		        XMLSEC_ERRORS_R_INVALID_DATA,
       
  1043 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1044 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1045             xmlFreeNode(result);
       
  1046 	    return(NULL);
       
  1047         }
       
  1048                 
       
  1049         break;
       
  1050 #endif /* XMLSEC_NO_SOAP */
       
  1051     default:
       
  1052     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1053 		    NULL,
       
  1054 		    NULL,
       
  1055 		    XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
       
  1056 		    "format=%d",
       
  1057                     format);
       
  1058 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
  1059 	return(NULL);
       
  1060     }
       
  1061     
       
  1062     return(result);
       
  1063 }
       
  1064 
       
  1065 #ifndef XMLSEC_NO_SOAP
       
  1066 static int 
       
  1067 xmlSecXkmsServerCtxWriteSoap11FatalError(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr envNode) {
       
  1068     const xmlChar* faultCodeHref = NULL;
       
  1069     const xmlChar* faultCodeLocalPart = NULL;
       
  1070     xmlChar* faultString = NULL;
       
  1071     int len;
       
  1072     
       
  1073     xmlSecAssert2(ctx != NULL, -1);
       
  1074     xmlSecAssert2(envNode != NULL, -1);
       
  1075 
       
  1076     if((ctx->resultMajor == xmlSecXkmsResultMajorVersionMismatch) ||
       
  1077        (ctx->requestNode == NULL)) {
       
  1078         /* we were not able to parse the envelope or its general version mismatch error */
       
  1079         faultCodeHref = xmlSecSoap11Ns;
       
  1080         faultCodeLocalPart = xmlSecSoapFaultCodeVersionMismatch;
       
  1081         faultString = xmlStrdup(xmlSecXkmsSoapFaultReasonUnsupportedVersion);
       
  1082         if(faultString == NULL) {
       
  1083             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1084 		        NULL,
       
  1085 		        "xmlStrdup",
       
  1086 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1087 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1088 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1089             return(-1);
       
  1090         }
       
  1091     } else if((ctx->resultMajor == xmlSecXkmsResultMajorSender) && 
       
  1092               (ctx->requestId == NULL)) {
       
  1093         /* we understood the request but were not able to parse input message */
       
  1094         faultCodeHref = xmlSecSoap11Ns;
       
  1095         faultCodeLocalPart = xmlSecSoapFaultCodeClient;
       
  1096 
       
  1097         len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) +
       
  1098               xmlStrlen(xmlSecXkmsSoapFaultReasonMessageInvalid) + 1;
       
  1099         faultString = xmlMalloc(len + 1);
       
  1100         if(faultString == NULL) {
       
  1101             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1102 		        NULL,
       
  1103 		        "xmlMalloc",
       
  1104 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1105 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1106 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1107             return(-1);
       
  1108         }
       
  1109         xmlSecStrPrintf(faultString, len , xmlSecXkmsSoapFaultReasonMessageInvalid,
       
  1110                         xmlSecErrorsSafeString(ctx->requestNode->name));        
       
  1111     } else if((ctx->resultMajor == xmlSecXkmsResultMajorReceiver) &&
       
  1112               (ctx->requestId == NULL)) {
       
  1113         /* we understood the request but were not able to process it */
       
  1114         faultCodeHref = xmlSecSoap11Ns;
       
  1115         faultCodeLocalPart = xmlSecSoapFaultCodeServer;
       
  1116         faultString = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
       
  1117         if(faultString == NULL) {
       
  1118             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1119 		        NULL,
       
  1120 		        "xmlStrdup",
       
  1121 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1122 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1123 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1124             return(-1);
       
  1125         }
       
  1126     } else if((ctx->requestId == NULL) && (ctx->requestNode != NULL)) {
       
  1127         /* we parsed the envelope but were not able to understand this request */
       
  1128         faultCodeHref = xmlSecSoap11Ns;
       
  1129         faultCodeLocalPart = xmlSecSoapFaultCodeClient;
       
  1130 
       
  1131         len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) + 
       
  1132               xmlStrlen(xmlSecXkmsSoapFaultReasonMessageNotSupported) + 1;
       
  1133         faultString = xmlMalloc(len + 1);
       
  1134         if(faultString == NULL) {
       
  1135             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1136 		        NULL,
       
  1137 		        "xmlMalloc",
       
  1138 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1139 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1140 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1141             return(-1);
       
  1142         }
       
  1143         xmlSecStrPrintf(faultString, len , xmlSecXkmsSoapFaultReasonMessageNotSupported,
       
  1144                         xmlSecErrorsSafeString(ctx->requestNode->name));
       
  1145     } else {
       
  1146         /* just some error */
       
  1147         faultCodeHref = xmlSecSoap11Ns;
       
  1148         faultCodeLocalPart = xmlSecSoapFaultCodeServer;
       
  1149         faultString = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
       
  1150         if(faultString == NULL) {
       
  1151             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1152 		        NULL,
       
  1153 		        "xmlStrdup",
       
  1154 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1155 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1156 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1157             return(-1);
       
  1158         }
       
  1159     }
       
  1160     
       
  1161     if(xmlSecSoap11AddFaultEntry(envNode, faultCodeHref, faultCodeLocalPart, faultString, NULL) == NULL) {
       
  1162         xmlSecError(XMLSEC_ERRORS_HERE,
       
  1163 		    NULL,
       
  1164 		    "xmlSecSoap11AddFaultEntry",
       
  1165 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1166 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1167 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1168         xmlFree(faultString);    
       
  1169         return(-1);
       
  1170     }
       
  1171 
       
  1172     xmlFree(faultString);    
       
  1173     return(0);
       
  1174 }
       
  1175 
       
  1176 static int 
       
  1177 xmlSecXkmsServerCtxWriteSoap12FatalError(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr envNode) {
       
  1178     xmlSecSoap12FaultCode faultCode = xmlSecSoap12FaultCodeUnknown;
       
  1179     const xmlChar* faultSubCodeHref = NULL;
       
  1180     const xmlChar* faultSubCodeLocalPart = NULL;
       
  1181     xmlChar* faultReason = NULL;
       
  1182     int len;
       
  1183     xmlNodePtr faultNode;
       
  1184     
       
  1185     xmlSecAssert2(ctx != NULL, -1);
       
  1186     xmlSecAssert2(envNode != NULL, -1);
       
  1187 
       
  1188     if((ctx->resultMajor == xmlSecXkmsResultMajorVersionMismatch) ||
       
  1189        (ctx->requestNode == NULL)) {
       
  1190         /* we were not able to parse the envelope or its general version mismatch error */
       
  1191         faultCode = xmlSecSoap12FaultCodeVersionMismatch;
       
  1192         faultReason = xmlStrdup(xmlSecXkmsSoapFaultReasonUnsupportedVersion);
       
  1193         if(faultReason == NULL) {
       
  1194             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1195 		        NULL,
       
  1196 		        "xmlStrdup",
       
  1197 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1198 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1199 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1200             return(-1);
       
  1201         }
       
  1202     } else if((ctx->resultMajor == xmlSecXkmsResultMajorSender) && 
       
  1203               (ctx->requestId == NULL)) {
       
  1204         /* we understood the request but were not able to parse input message */
       
  1205         faultCode = xmlSecSoap12FaultCodeSender;
       
  1206         faultSubCodeHref = xmlSecXkmsNs;
       
  1207         faultSubCodeLocalPart = xmlSecXkmsSoapSubcodeValueMessageNotSupported;
       
  1208 
       
  1209         len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) +
       
  1210               xmlStrlen(xmlSecXkmsSoapFaultReasonMessageInvalid) + 1;
       
  1211         faultReason = xmlMalloc(len + 1);
       
  1212         if(faultReason == NULL) {
       
  1213             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1214 		        NULL,
       
  1215 		        "xmlMalloc",
       
  1216 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1217 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1218 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1219             return(-1);
       
  1220         }
       
  1221         xmlSecStrPrintf(faultReason, len , xmlSecXkmsSoapFaultReasonMessageInvalid,
       
  1222                         xmlSecErrorsSafeString(ctx->requestNode->name));        
       
  1223     } else if((ctx->resultMajor == xmlSecXkmsResultMajorReceiver) &&
       
  1224               (ctx->requestId == NULL)) {
       
  1225         /* we understood the request but were not able to process it */
       
  1226         faultCode = xmlSecSoap12FaultCodeReceiver;
       
  1227         faultReason = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
       
  1228         if(faultReason == NULL) {
       
  1229             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1230 		        NULL,
       
  1231 		        "xmlStrdup",
       
  1232 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1233 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1234 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1235             return(-1);
       
  1236         }
       
  1237     } else if((ctx->requestId == NULL) && (ctx->requestNode != NULL)) {
       
  1238         /* we parsed the envelope but were not able to understand this request */
       
  1239         faultCode = xmlSecSoap12FaultCodeSender;
       
  1240         faultSubCodeHref = xmlSecXkmsNs;
       
  1241         faultSubCodeLocalPart = xmlSecXkmsSoapSubcodeValueBadMessage;
       
  1242 
       
  1243         len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) + 
       
  1244               xmlStrlen(xmlSecXkmsSoapFaultReasonMessageNotSupported) + 1;
       
  1245         faultReason = xmlMalloc(len + 1);
       
  1246         if(faultReason == NULL) {
       
  1247             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1248 		        NULL,
       
  1249 		        "xmlMalloc",
       
  1250 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1251 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1252 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1253             return(-1);
       
  1254         }
       
  1255         xmlSecStrPrintf(faultReason, len , xmlSecXkmsSoapFaultReasonMessageNotSupported,
       
  1256                         xmlSecErrorsSafeString(ctx->requestNode->name));
       
  1257     } else {
       
  1258         /* just some error */
       
  1259         faultCode = xmlSecSoap12FaultCodeReceiver;
       
  1260         faultReason = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
       
  1261         if(faultReason == NULL) {
       
  1262             xmlSecError(XMLSEC_ERRORS_HERE,
       
  1263 		        NULL,
       
  1264 		        "xmlStrdup",
       
  1265 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1266 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  1267 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1268             return(-1);
       
  1269         }
       
  1270     }
       
  1271     xmlSecAssert2(faultCode != xmlSecSoap12FaultCodeUnknown, -1);
       
  1272     xmlSecAssert2(faultReason != NULL, -1);
       
  1273     
       
  1274     faultNode = xmlSecSoap12AddFaultEntry(envNode, faultCode, faultReason, 
       
  1275                                     xmlSecXkmsSoapFaultReasonLang, NULL, NULL);
       
  1276     if(faultNode == NULL) {
       
  1277         xmlSecError(XMLSEC_ERRORS_HERE,
       
  1278 		    NULL,
       
  1279 		    "xmlSecSoap12AddFaultEntry",
       
  1280 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1281 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1282 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  1283         xmlFree(faultReason);    
       
  1284         return(-1);
       
  1285     }
       
  1286     xmlFree(faultReason);    
       
  1287 
       
  1288     if((faultSubCodeHref != NULL) && (faultSubCodeLocalPart != NULL)) {
       
  1289         /* make sure that we have subcode (xkms) namespace declared */
       
  1290         if(xmlNewNs(faultNode, faultSubCodeHref, BAD_CAST "xkms") == NULL) {
       
  1291 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1292 		        NULL,
       
  1293 		        "xmlNewNs",
       
  1294 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1295 		        "ns=%s",
       
  1296 		        xmlSecErrorsSafeString(faultSubCodeHref));
       
  1297             return(-1);
       
  1298         }
       
  1299         if(xmlSecSoap12AddFaultSubcode(faultNode, faultSubCodeHref, faultSubCodeLocalPart) == NULL) {
       
  1300 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1301 		        NULL,
       
  1302 		        "xmlSecSoap12AddFaultSubcode",
       
  1303 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1304 		        "href=%s,value=%s",
       
  1305 		        xmlSecErrorsSafeString(faultSubCodeHref),
       
  1306 		        xmlSecErrorsSafeString(faultSubCodeLocalPart));
       
  1307             return(-1);
       
  1308         }
       
  1309     }
       
  1310 
       
  1311     return(0);
       
  1312 }
       
  1313 
       
  1314 #endif /* XMLSEC_NO_SOAP */
       
  1315 
       
  1316 
       
  1317 /** 
       
  1318  * xmlSecXkmsServerCtxSetResult: 
       
  1319  * @ctx:	 the pointer to XKMS processing context.
       
  1320  * @resultMajor: the major result code.
       
  1321  * @resultMinor: the minor result code.
       
  1322  * 
       
  1323  * Sets the major/minor result code in the context if no other result is already
       
  1324  * reported.
       
  1325  */
       
  1326 EXPORT_C
       
  1327 void 
       
  1328 xmlSecXkmsServerCtxSetResult(xmlSecXkmsServerCtxPtr ctx, xmlSecXkmsResultMajor resultMajor, 
       
  1329                              xmlSecXkmsResultMinor resultMinor) {
       
  1330     xmlSecAssert(ctx != NULL);
       
  1331     
       
  1332     if((ctx->resultMajor == xmlSecXkmsResultMajorSuccess) && 
       
  1333        (resultMinor != xmlSecXkmsResultMajorSuccess)) {
       
  1334 	ctx->resultMajor = resultMajor;
       
  1335 	ctx->resultMinor = resultMinor;
       
  1336     } else if((ctx->resultMajor == xmlSecXkmsResultMajorSuccess) && 
       
  1337        (ctx->resultMinor == xmlSecXkmsResultMinorNone)) {
       
  1338 	xmlSecAssert(resultMajor == xmlSecXkmsResultMajorSuccess);
       
  1339 	
       
  1340 	ctx->resultMinor = resultMinor;
       
  1341     }
       
  1342 }
       
  1343 
       
  1344 
       
  1345 /**
       
  1346  * xmlSecXkmsServerCtxDebugDump:
       
  1347  * @ctx:	the pointer to XKMS processing context.
       
  1348  * @output:	the pointer to output FILE.
       
  1349  *
       
  1350  * Prints the debug information about @ctx to @output.
       
  1351  */
       
  1352 EXPORT_C
       
  1353 void 
       
  1354 xmlSecXkmsServerCtxDebugDump(xmlSecXkmsServerCtxPtr ctx, FILE* output) {
       
  1355     xmlSecAssert(ctx != NULL);
       
  1356     xmlSecAssert(output != NULL);
       
  1357     
       
  1358     fprintf(output, "= XKMS SERVER CONTEXT: %s\n",
       
  1359 	    (ctx->requestId != xmlSecXkmsServerRequestIdUnknown && 
       
  1360 	     xmlSecXkmsServerRequestKlassGetName(ctx->requestId)) ? 
       
  1361 		xmlSecXkmsServerRequestKlassGetName(ctx->requestId) :
       
  1362 		BAD_CAST "NULL");
       
  1363 
       
  1364     xmlSecQName2IntegerDebugDump(gXmlSecXkmsResultMajorInfo, 
       
  1365 		ctx->resultMajor, BAD_CAST "resultMajor", output);    
       
  1366     xmlSecQName2IntegerDebugDump(gXmlSecXkmsMinorErrorInfo, 
       
  1367 		ctx->resultMinor, BAD_CAST "resultMinor", output);    
       
  1368 
       
  1369     fprintf(output, "== id: %s\n", 
       
  1370 		(ctx->id) ? ctx->id : BAD_CAST "");
       
  1371     fprintf(output, "== service: %s\n", 
       
  1372 		(ctx->service) ? ctx->service : BAD_CAST "");
       
  1373     fprintf(output, "== nonce: %s\n", 
       
  1374 		(ctx->nonce) ? ctx->nonce : BAD_CAST "");
       
  1375     fprintf(output, "== originalRequestId: %s\n", 
       
  1376 		(ctx->originalRequestId) ? ctx->originalRequestId : BAD_CAST "");
       
  1377     fprintf(output, "== pendingNotificationMechanism: %s\n", 
       
  1378 		(ctx->pendingNotificationMechanism) ? 
       
  1379 		    ctx->pendingNotificationMechanism : 
       
  1380 		    BAD_CAST "");
       
  1381     fprintf(output, "== pendingNotificationIdentifier: %s\n", 
       
  1382 		(ctx->pendingNotificationIdentifier) ? 
       
  1383 		    ctx->pendingNotificationIdentifier : 
       
  1384 		    BAD_CAST "");
       
  1385     if(ctx->responseLimit != XMLSEC_XKMS_NO_RESPONSE_LIMIT) {
       
  1386         fprintf(output, "== ResponseLimit: %d\n", ctx->responseLimit);
       
  1387     }
       
  1388     xmlSecQName2BitMaskDebugDump(gXmlSecXkmsResponseMechanismInfo, 
       
  1389 		ctx->responseMechanismMask, BAD_CAST "responseMechanism", output);    
       
  1390 
       
  1391     if(ctx->expectedService != NULL) {    
       
  1392         fprintf(output, "== expected service: %s\n", ctx->expectedService);
       
  1393     }
       
  1394     fprintf(output, "== flags: 0x%08x\n", ctx->flags);
       
  1395     fprintf(output, "== flags2: 0x%08x\n", ctx->flags2);
       
  1396 
       
  1397     fprintf(output, "== Key Info Read Ctx:\n");
       
  1398     xmlSecKeyInfoCtxDebugDump(&(ctx->keyInfoReadCtx), output);
       
  1399     
       
  1400     fprintf(output, "== Key Info Write Ctx:\n");
       
  1401     xmlSecKeyInfoCtxDebugDump(&(ctx->keyInfoWriteCtx), output);
       
  1402 
       
  1403     if(xmlSecPtrListGetSize(&(ctx->enabledRespondWithIds)) > 0) {
       
  1404 	fprintf(output, "== Enabled RespondWith: ");
       
  1405 	xmlSecTransformIdListDebugDump(&(ctx->enabledRespondWithIds), output);
       
  1406     } else {
       
  1407 	fprintf(output, "== Enabled RespondWith: all\n");
       
  1408     }
       
  1409 
       
  1410     if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
       
  1411 	fprintf(output, "== Enabled ServerRequest: ");
       
  1412 	xmlSecTransformIdListDebugDump(&(ctx->enabledServerRequestIds), output);
       
  1413     } else {
       
  1414 	fprintf(output, "== Enabled ServerRequest: all\n");
       
  1415     }
       
  1416 
       
  1417     fprintf(output, "== RespondWith List:\n");
       
  1418     xmlSecPtrListDebugDump(&(ctx->respWithList), output);
       
  1419 
       
  1420     fprintf(output, "== Keys:\n");
       
  1421     xmlSecPtrListDebugDump(&(ctx->keys), output);
       
  1422     
       
  1423     if(ctx->compoundRequestContexts != NULL) {
       
  1424         fprintf(output, "== Compound Request:\n");
       
  1425         xmlSecPtrListDebugDump(ctx->compoundRequestContexts, output);
       
  1426     }
       
  1427 }
       
  1428 
       
  1429 /**
       
  1430  * xmlSecXkmsServerCtxDebugXmlDump:
       
  1431  * @ctx:	the pointer to XKMS processing context.
       
  1432  * @output:	the pointer to output FILE.
       
  1433  *
       
  1434  * Prints the debug information about @ctx to @output in XML format.
       
  1435  */
       
  1436 EXPORT_C
       
  1437 void 
       
  1438 xmlSecXkmsServerCtxDebugXmlDump(xmlSecXkmsServerCtxPtr ctx, FILE* output) {
       
  1439     xmlSecAssert(ctx != NULL);
       
  1440     xmlSecAssert(output != NULL);
       
  1441 
       
  1442     fprintf(output, "<XkmsServerRequestContext name=\"%s\">\n",
       
  1443 	    (ctx->requestId != xmlSecXkmsServerRequestIdUnknown && 
       
  1444 	     xmlSecXkmsServerRequestKlassGetName(ctx->requestId)) ? 
       
  1445 		xmlSecXkmsServerRequestKlassGetName(ctx->requestId) :
       
  1446 		BAD_CAST "NULL");
       
  1447 
       
  1448     xmlSecQName2IntegerDebugXmlDump(gXmlSecXkmsResultMajorInfo, 
       
  1449 		ctx->resultMajor, BAD_CAST "MajorError", output);    
       
  1450     xmlSecQName2IntegerDebugXmlDump(gXmlSecXkmsMinorErrorInfo, 
       
  1451 		ctx->resultMinor, BAD_CAST "MinorError", output);    
       
  1452 
       
  1453     fprintf(output, "<Id>%s</Id>\n", 
       
  1454 		(ctx->id) ? ctx->id : BAD_CAST "");
       
  1455     fprintf(output, "<Service>%s</Service>\n", 
       
  1456 		(ctx->service) ? ctx->service : BAD_CAST "");
       
  1457     fprintf(output, "<Nonce>%s</Nonce>\n", 
       
  1458 		(ctx->nonce) ? ctx->nonce : BAD_CAST "");
       
  1459     fprintf(output, "<OriginalRequestId>%s</OriginalRequestId>\n", 
       
  1460 		(ctx->originalRequestId) ? ctx->originalRequestId : BAD_CAST "");
       
  1461     fprintf(output, "<PendingNotificationMechanism>%s</PendingNotificationMechanism>\n", 
       
  1462 		(ctx->pendingNotificationMechanism) ? 
       
  1463 		    ctx->pendingNotificationMechanism : 
       
  1464 		    BAD_CAST "");
       
  1465     fprintf(output, "<PendingNotificationIdentifier>%s</PendingNotificationIdentifier>\n", 
       
  1466 		(ctx->pendingNotificationIdentifier) ? 
       
  1467 		    ctx->pendingNotificationIdentifier : 
       
  1468 		    BAD_CAST "");
       
  1469     if(ctx->responseLimit != XMLSEC_XKMS_NO_RESPONSE_LIMIT) {
       
  1470         fprintf(output, "<ResponseLimit>%d</ResponseLimit>\n", ctx->responseLimit);
       
  1471     }
       
  1472     xmlSecQName2BitMaskDebugXmlDump(gXmlSecXkmsResponseMechanismInfo, 
       
  1473 		ctx->responseMechanismMask, BAD_CAST "ResponseMechanism", output);    
       
  1474 
       
  1475 
       
  1476     if(ctx->expectedService != NULL) {    
       
  1477         fprintf(output, "<ExpectedService>%s</ExpectedService>\n", ctx->expectedService);
       
  1478     }
       
  1479     fprintf(output, "<Flags>%08x</Flags>\n", ctx->flags);
       
  1480     fprintf(output, "<Flags2>%08x</Flags2>\n", ctx->flags2);
       
  1481 
       
  1482     fprintf(output, "<KeyInfoReadCtx>\n");
       
  1483     xmlSecKeyInfoCtxDebugXmlDump(&(ctx->keyInfoReadCtx), output);
       
  1484     fprintf(output, "</KeyInfoReadCtx>\n");
       
  1485 
       
  1486     fprintf(output, "<KeyInfoWriteCtx>\n");
       
  1487     xmlSecKeyInfoCtxDebugXmlDump(&(ctx->keyInfoWriteCtx), output);
       
  1488     fprintf(output, "</KeyInfoWriteCtx>\n");
       
  1489 
       
  1490     if(xmlSecPtrListGetSize(&(ctx->enabledRespondWithIds)) > 0) {
       
  1491 	fprintf(output, "<EnabledRespondWith>\n");
       
  1492 	xmlSecTransformIdListDebugXmlDump(&(ctx->enabledRespondWithIds), output);
       
  1493 	fprintf(output, "</EnabledRespondWith>\n");
       
  1494     } else {
       
  1495 	fprintf(output, "<EnabledRespondWith>all</EnabledRespondWith>\n");
       
  1496     }
       
  1497 
       
  1498     if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
       
  1499 	fprintf(output, "<EnabledServerRequest>\n");
       
  1500 	xmlSecTransformIdListDebugXmlDump(&(ctx->enabledServerRequestIds), output);
       
  1501 	fprintf(output, "</EnabledServerRequest>\n");
       
  1502     } else {
       
  1503 	fprintf(output, "<EnabledServerRequest>all</EnabledServerRequest>\n");
       
  1504     }
       
  1505 
       
  1506 
       
  1507     fprintf(output, "<RespondWithList>\n");
       
  1508     xmlSecPtrListDebugXmlDump(&(ctx->respWithList), output);
       
  1509     fprintf(output, "</RespondWithList>\n");
       
  1510 
       
  1511     fprintf(output, "<Keys>\n");
       
  1512     xmlSecPtrListDebugXmlDump(&(ctx->keys), output);
       
  1513     fprintf(output, "</Keys>\n");
       
  1514 
       
  1515     if(ctx->compoundRequestContexts != NULL) {
       
  1516         fprintf(output, "<CompoundRequest>\n");
       
  1517         xmlSecPtrListDebugXmlDump(ctx->compoundRequestContexts, output);
       
  1518         fprintf(output, "</CompoundRequest>\n");
       
  1519     }
       
  1520 
       
  1521     fprintf(output, "</XkmsServerRequestContext>\n");
       
  1522 }
       
  1523 
       
  1524 /**
       
  1525  *  <xkms:MessageAbstractType Id Service Nonce?>
       
  1526  *      <ds:Signature>?
       
  1527  *      <xkms:MessageExtension>*
       
  1528  *      (<xkms:OpaqueClientData>
       
  1529  *          <xkms:OpaqueData>?
       
  1530  *      )?
       
  1531  *  
       
  1532  *  <xkms:RequestAbstractType Id Service Nonce? OriginalRequestId? ResponseLimit?>
       
  1533  *      <ds:Signature>?
       
  1534  *      <xkms:MessageExtension>*
       
  1535  *      (<xkms:OpaqueClientData>
       
  1536  *          <xkms:OpaqueData>?
       
  1537  *      )?
       
  1538  *      <xkms:ResponseMechanism>*
       
  1539  *      <xkms:RespondWith>*
       
  1540  *      <xkms:PendingNotification Mechanism Identifier>?
       
  1541  *
       
  1542  * XML Schema:
       
  1543  *
       
  1544  *   <!-- RequestAbstractType -->
       
  1545  *   <complexType name="RequestAbstractType" abstract="true">
       
  1546  *      <complexContent>
       
  1547  *         <extension base="xkms:MessageAbstractType">
       
  1548  *            <sequence>
       
  1549  *              <element ref="xkms:ResponseMechanism" minOccurs="0" 
       
  1550  *                     maxOccurs="unbounded"/>
       
  1551  *               <element ref="xkms:RespondWith" minOccurs="0" 
       
  1552  *                     maxOccurs="unbounded"/>
       
  1553  *               <element ref="xkms:PendingNotification" minOccurs="0"/>
       
  1554  *            </sequence>
       
  1555  *            <attribute name="OriginalRequestId" type="anyURI" 
       
  1556  *                  use="optional"/>
       
  1557  *            <attribute name="ResponseLimit" type="integer" use="optional"/>
       
  1558  *         </extension>
       
  1559  *      </complexContent>
       
  1560  *   </complexType>
       
  1561  *   <!-- /RequestAbstractType -->
       
  1562  *
       
  1563  *   <!-- MessageAbstractType -->
       
  1564  *   <complexType name="MessageAbstractType" abstract="true">
       
  1565  *      <sequence>
       
  1566  *         <element ref="ds:Signature" minOccurs="0"/>
       
  1567  *         <element ref="xkms:MessageExtension" minOccurs="0" 
       
  1568  *               maxOccurs="unbounded"/>
       
  1569  *         <element ref="xkms:OpaqueClientData" minOccurs="0"/>
       
  1570  *      </sequence>
       
  1571  *      <attribute name="Id" type="ID" use="required"/>
       
  1572  *      <attribute name="Service" type="anyURI" use="required"/>
       
  1573  *      <attribute name="Nonce" type="base64Binary" use="optional"/>
       
  1574  *   </complexType>
       
  1575  *   <!-- /MessageAbstractType -->
       
  1576  */
       
  1577 static int 
       
  1578 xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
       
  1579     xmlNodePtr cur;
       
  1580     xmlChar* tmp;
       
  1581     int ret;
       
  1582 
       
  1583     xmlSecAssert2(ctx != NULL, -1);
       
  1584     xmlSecAssert2(node != NULL, -1);
       
  1585     xmlSecAssert2((*node) != NULL, -1);
       
  1586     
       
  1587     cur = (*node);
       
  1588     xmlSecAssert2(cur != NULL, -1);
       
  1589 
       
  1590     /* required Id attribute */
       
  1591     xmlSecAssert2(ctx->id == NULL, -1);
       
  1592     ctx->id = xmlGetProp(cur, xmlSecAttrId);
       
  1593     if(ctx->id == NULL) {
       
  1594     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1595 		    NULL,
       
  1596 		    "xmlGetProp",
       
  1597 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  1598 		    "name=%s;node=%s",
       
  1599 		    xmlSecErrorsSafeString(xmlSecAttrId),
       
  1600 		    xmlSecErrorsSafeString(cur->name));
       
  1601 	return(-1);
       
  1602     }
       
  1603     
       
  1604     /* required Service attribute */
       
  1605     xmlSecAssert2(ctx->service == NULL, -1);
       
  1606     ctx->service = xmlGetProp(cur, xmlSecAttrService);
       
  1607     if(ctx->service == NULL) {
       
  1608     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1609 		    NULL,
       
  1610 		    "xmlGetProp",
       
  1611 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  1612 		    "name=%s;node=%s",
       
  1613 		    xmlSecErrorsSafeString(xmlSecAttrService),
       
  1614 		    xmlSecErrorsSafeString(cur->name));
       
  1615 	return(-1);
       
  1616     }
       
  1617     
       
  1618     /* check service */
       
  1619     if((ctx->expectedService != NULL) && (!xmlStrEqual(ctx->expectedService, ctx->service))) {
       
  1620     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1621 		    NULL,
       
  1622 		    NULL,
       
  1623 		    XMLSEC_ERRORS_R_INVALID_DATA,
       
  1624 		    "expectedService=%s;actualService=%s",
       
  1625 		    xmlSecErrorsSafeString(ctx->expectedService),
       
  1626 		    xmlSecErrorsSafeString(ctx->service));
       
  1627 	return(-1);
       
  1628     }
       
  1629 
       
  1630     /* optional Nonce attribute */
       
  1631     xmlSecAssert2(ctx->nonce == NULL, -1);
       
  1632     ctx->nonce = xmlGetProp(cur, xmlSecAttrNonce);
       
  1633 
       
  1634     /* optional OriginalRequestId attribute */
       
  1635     xmlSecAssert2(ctx->originalRequestId == NULL, -1);
       
  1636     ctx->originalRequestId = xmlGetProp(cur, xmlSecAttrOriginalRequestId);
       
  1637 
       
  1638     /* optional ResponseLimit attribute */
       
  1639     xmlSecAssert2(ctx->responseLimit == XMLSEC_XKMS_NO_RESPONSE_LIMIT, -1);
       
  1640     tmp = xmlGetProp(cur, xmlSecAttrResponseLimit);
       
  1641     if(tmp != NULL) {
       
  1642 	ctx->responseLimit = atoi((char*)tmp);
       
  1643 	xmlFree(tmp);
       
  1644     }
       
  1645 
       
  1646     /* now read children */   
       
  1647     cur = xmlSecGetNextElementNode(cur->children);
       
  1648     
       
  1649     /* first node is optional <dsig:Signature/> node */
       
  1650     if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeSignature, xmlSecDSigNs)) {
       
  1651 	ret = xmlSecXkmsServerCtxSignatureNodeRead(ctx, cur);
       
  1652 	if(ret < 0) {
       
  1653     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1654 		        NULL,
       
  1655 		        "xmlSecXkmsServerCtxSignatureNodeRead",
       
  1656 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1657 			XMLSEC_ERRORS_NO_MESSAGE);
       
  1658 	    return(-1);
       
  1659 	}
       
  1660 	cur = xmlSecGetNextElementNode(cur->next);
       
  1661     }
       
  1662     
       
  1663     /* next is zero or more <xkms:MessageExtension/> nodes */
       
  1664     ret = xmlSecXkmsServerCtxMessageExtensionNodesRead(ctx, &cur);
       
  1665     if(ret < 0) {
       
  1666     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1667 		    NULL,
       
  1668 		    "xmlSecXkmsServerCtxMessageExtensionNodesRead",
       
  1669 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1670 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1671 	return(-1);
       
  1672     }
       
  1673     
       
  1674     /* next is optional <xkms:OpaqueClientData/> node */
       
  1675     if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeOpaqueClientData, xmlSecXkmsNs)) {
       
  1676 	ret = xmlSecXkmsServerCtxOpaqueClientDataNodeRead(ctx, cur);
       
  1677 	if(ret < 0) {
       
  1678     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1679 		        NULL,
       
  1680 		        "xmlSecXkmsServerCtxOpaqueClientDataNodeRead",
       
  1681 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1682 			XMLSEC_ERRORS_NO_MESSAGE);
       
  1683 	    return(-1);
       
  1684 	}
       
  1685 	cur = xmlSecGetNextElementNode(cur->next);
       
  1686     }
       
  1687 
       
  1688     /* next is zero or more <xkms:ResponseMechanism/> nodes */
       
  1689     ret = xmlSecQName2BitMaskNodesRead(gXmlSecXkmsResponseMechanismInfo, &cur, 
       
  1690 			xmlSecNodeResponseMechanism, xmlSecXkmsNs,
       
  1691                         ((ctx->flags & XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_RESPONSE_MECHANISM) != 0) ? 1 : 0, 
       
  1692 			&ctx->responseMechanismMask);
       
  1693     if(ret < 0) {
       
  1694     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1695 		    NULL,
       
  1696 		    "xmlSecQName2BitMaskNodesRead",
       
  1697 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1698 		    "name=%s",
       
  1699 		    xmlSecErrorsSafeString(xmlSecNodeResponseMechanism));
       
  1700 	return(-1);
       
  1701     }
       
  1702     
       
  1703     /* next is zero or more <xkms:RespondWith/> nodes */
       
  1704     ret = xmlSecXkmsServerCtxRespondWithNodesRead(ctx, &cur);
       
  1705     if(ret < 0) {
       
  1706     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1707 		    NULL,
       
  1708 		    "xmlSecXkmsServerCtxRespondWithNodesRead",
       
  1709 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1710 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1711 	return(-1);
       
  1712     }
       
  1713 
       
  1714     /* next is optional <xkms:PendingNotification/> node */
       
  1715     if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodePendingNotification, xmlSecXkmsNs)) {
       
  1716 	ret = xmlSecXkmsServerCtxPendingNotificationNodeRead(ctx, cur);    
       
  1717 	if(ret < 0) {
       
  1718     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1719 		        NULL,
       
  1720 		        "xmlSecXkmsServerCtxPendingNotificationNodeRead",
       
  1721 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1722 			XMLSEC_ERRORS_NO_MESSAGE);
       
  1723 	    return(-1);
       
  1724 	}
       
  1725 	cur = xmlSecGetNextElementNode(cur->next);
       
  1726     }
       
  1727 
       
  1728     (*node) = cur;    
       
  1729     return(0);
       
  1730 }
       
  1731 
       
  1732 static int 
       
  1733 xmlSecXkmsServerCtxSignatureNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  1734     xmlSecAssert2(ctx != NULL, -1);
       
  1735     xmlSecAssert2(node != NULL, -1);
       
  1736     
       
  1737     return(0);
       
  1738 }
       
  1739 
       
  1740 /** 
       
  1741  *   <!-- MessageExtension -->
       
  1742  *   <element name="MessageExtension" type="xkms:MessageExtensionAbstractType"
       
  1743  *         abstract="true"/>
       
  1744  *   <complexType name="MessageExtensionAbstractType" abstract="true"/>
       
  1745  *   <!-- /MessageExtension -->
       
  1746  */
       
  1747 static int
       
  1748 xmlSecXkmsServerCtxMessageExtensionNodesRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
       
  1749     xmlNodePtr cur;
       
  1750 
       
  1751     xmlSecAssert2(ctx != NULL, -1);
       
  1752     xmlSecAssert2(ctx->firtsMsgExtNode == NULL, -1);
       
  1753     xmlSecAssert2(node != NULL, -1);
       
  1754 
       
  1755     cur = (*node);
       
  1756     while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeMessageExtension, xmlSecXkmsNs)) {
       
  1757 	if(ctx->firtsMsgExtNode == NULL) {
       
  1758 	    ctx->firtsMsgExtNode = cur;
       
  1759 	}
       
  1760 	cur = xmlSecGetNextElementNode(cur->next);
       
  1761     }
       
  1762 
       
  1763     (*node) = cur;    
       
  1764     return(0);
       
  1765 }
       
  1766 
       
  1767 static int 
       
  1768 xmlSecXkmsServerCtxOpaqueClientDataNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  1769     xmlSecAssert2(ctx != NULL, -1);
       
  1770     xmlSecAssert2(ctx->opaqueClientDataNode == NULL, -1);
       
  1771     xmlSecAssert2(node != NULL, -1);
       
  1772 
       
  1773     /* remember that node, will copy it in the response later */
       
  1774     ctx->opaqueClientDataNode = node;
       
  1775     return(0);
       
  1776 }
       
  1777 
       
  1778 static int
       
  1779 xmlSecXkmsServerCtxRespondWithNodesRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
       
  1780     xmlNodePtr cur;
       
  1781     int ret;
       
  1782 
       
  1783     xmlSecAssert2(ctx != NULL, -1);
       
  1784     xmlSecAssert2(node != NULL, -1);
       
  1785 
       
  1786     cur = (*node);
       
  1787     while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeRespondWith, xmlSecXkmsNs)) {
       
  1788 	xmlSecXkmsRespondWithId id = xmlSecXkmsRespondWithIdUnknown;
       
  1789 
       
  1790 	if(xmlSecPtrListGetSize(&(ctx->enabledRespondWithIds)) > 0) {
       
  1791 	    id = xmlSecXkmsRespondWithIdListFindByNodeValue(&(ctx->enabledRespondWithIds), cur);
       
  1792 	} else {
       
  1793 	    id = xmlSecXkmsRespondWithIdListFindByNodeValue(xmlSecXkmsRespondWithIdsGet(), cur);	
       
  1794 	}
       
  1795 
       
  1796 	if(id != xmlSecXkmsRespondWithIdUnknown) {	
       
  1797 	    ret = xmlSecXkmsRespondWithNodeRead(id, ctx, cur);
       
  1798 	    if(ret < 0) {
       
  1799 	        xmlSecError(XMLSEC_ERRORS_HERE,
       
  1800 			    NULL,
       
  1801 			    "xmlSecCreateTree",
       
  1802 			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1803 			    XMLSEC_ERRORS_NO_MESSAGE);
       
  1804 		return(-1);
       
  1805 	    }
       
  1806 	} else if((ctx->flags & XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_RESPOND_WITH) != 0) {
       
  1807             xmlChar* content ;
       
  1808             
       
  1809             content = xmlNodeGetContent(cur);
       
  1810     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1811 			NULL,
       
  1812 			NULL,
       
  1813 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1814 			"name=%s,value=%s",
       
  1815                         xmlSecErrorsSafeString(cur->name),
       
  1816                         xmlSecErrorsSafeString(content));
       
  1817             if(content != NULL) {
       
  1818                 xmlFree(content);
       
  1819             }
       
  1820 	    return(-1);
       
  1821 	}
       
  1822 	cur = xmlSecGetNextElementNode(cur->next);
       
  1823     }
       
  1824     
       
  1825     (*node) = cur;    
       
  1826     return(0);
       
  1827 }
       
  1828 
       
  1829 /** 
       
  1830  * XML Schema:
       
  1831  *   <!-- PendingNotification -->
       
  1832  *   <element name="PendingNotification" type="xkms:PendingNotificationType"/>
       
  1833  *   <complexType name="PendingNotificationType">
       
  1834  *      <attribute name="Mechanism" type="anyURI" use="required"/>
       
  1835  *      <attribute name="Identifier" type="anyURI" use="required"/>
       
  1836  *   </complexType>
       
  1837  *   <!-- /PendingNotification -->
       
  1838  */
       
  1839 static int 
       
  1840 xmlSecXkmsServerCtxPendingNotificationNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  1841     xmlSecAssert2(ctx != NULL, -1);
       
  1842     xmlSecAssert2(node != NULL, -1);
       
  1843 
       
  1844     xmlSecAssert2(ctx->pendingNotificationMechanism == NULL, -1);
       
  1845     ctx->pendingNotificationMechanism = xmlGetProp(node, xmlSecAttrMechanism);
       
  1846     if(ctx->pendingNotificationMechanism == NULL) {
       
  1847 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1848 		    NULL,
       
  1849 		    "xmlGetProp",
       
  1850 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  1851 		    "name=%s;node=%s",
       
  1852 		    xmlSecErrorsSafeString(xmlSecAttrMechanism),
       
  1853 		    xmlSecErrorsSafeString(node->name));
       
  1854     	return(-1);
       
  1855     }
       
  1856 
       
  1857     xmlSecAssert2(ctx->pendingNotificationIdentifier == NULL, -1);
       
  1858     ctx->pendingNotificationIdentifier = xmlGetProp(node, xmlSecAttrIdentifier);
       
  1859     if(ctx->pendingNotificationIdentifier == NULL) {
       
  1860 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1861 		    NULL,
       
  1862 		    "xmlGetProp",
       
  1863 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  1864 		    "name=%s;node=%s",
       
  1865 		    xmlSecErrorsSafeString(xmlSecAttrIdentifier),
       
  1866 		    xmlSecErrorsSafeString(node->name));
       
  1867     	return(-1);
       
  1868     }
       
  1869     
       
  1870     return(0);
       
  1871 }
       
  1872 
       
  1873 /**
       
  1874  *  <xkms:PendingRequestType Id Service Nonce? OriginalRequestId? ResponseLimit? ResponseId?>
       
  1875  *      <ds:Signature>?
       
  1876  *      <xkms:MessageExtension>*
       
  1877  *      (<xkms:OpaqueClientData>
       
  1878  *          <xkms:OpaqueData>?
       
  1879  *      )?
       
  1880  *      <xkms:ResponseMechanism>*
       
  1881  *      <xkms:RespondWith>*
       
  1882  *      <xkms:PendingNotification Mechanism Identifier>?
       
  1883  *  
       
  1884  * XML Schema:
       
  1885  *
       
  1886  *   <!-- PendingRequest -->  
       
  1887  *   <element name="PendingRequest" type="xkms:PendingRequestType"/>   
       
  1888  *   <complexType name="PendingRequestType">
       
  1889  *       <complexContent>
       
  1890  *           <extension base="xkms:RequestAbstractType">
       
  1891  *               <attribute name="ResponseId" type="anyURI" use="optional"/>
       
  1892  *            </extension>
       
  1893  *       </complexContent>
       
  1894  *    </complexType>
       
  1895  *    <!-- /PendingRequest --> * 
       
  1896  */
       
  1897 static int 
       
  1898 xmlSecXkmsServerCtxPendingRequestNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
       
  1899     int ret;
       
  1900 
       
  1901     xmlSecAssert2(ctx != NULL, -1);
       
  1902     xmlSecAssert2(node != NULL, -1);
       
  1903     
       
  1904     /* first read "parent" type */
       
  1905     ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, node);
       
  1906     if(ret < 0) {
       
  1907     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1908 		    NULL,
       
  1909 		    "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
       
  1910 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1911 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1912 	return(-1);
       
  1913     }
       
  1914 
       
  1915     return(0);
       
  1916 }
       
  1917 
       
  1918 /**
       
  1919  *  <xkms:QueryKeyBinding Id?
       
  1920  *      <ds:KeyInfo>?
       
  1921  *      <xkms:KeyUsage>?
       
  1922  *      <xkms:KeyUsage>?
       
  1923  *      <xkms:KeyUsage>?
       
  1924  *      <xkms:UseKeyWith Application Identifier>*    
       
  1925  *      <xkms:TimeInstant Time>?
       
  1926  *  
       
  1927  * XML Schema:
       
  1928  *   <!-- QueryKeyBinding -->
       
  1929  *   <element name="QueryKeyBinding" type="xkms:QueryKeyBindingType"/>
       
  1930  *   <complexType name="QueryKeyBindingType">
       
  1931  *      <complexContent>
       
  1932  *          <extension base="xkms:KeyBindingAbstractType">
       
  1933  *	        <sequence>
       
  1934  *		    <element ref="xkms:TimeInstant" minOccurs="0"/>
       
  1935  *		</sequence>
       
  1936  *	    </extension>
       
  1937  *	</complexContent>
       
  1938  *   </complexType>
       
  1939  *   <!-- /QueryKeyBinding -->
       
  1940  */
       
  1941 static int 
       
  1942 xmlSecXkmsServerCtxQueryKeyBindingNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  1943     xmlNodePtr cur;
       
  1944     int ret;
       
  1945     
       
  1946     xmlSecAssert2(ctx != NULL, -1);
       
  1947     xmlSecAssert2(node != NULL, -1);
       
  1948     
       
  1949     /* first read "parent" type */
       
  1950     cur = node;
       
  1951     ret = xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead(ctx, &cur);
       
  1952     if(ret < 0) {
       
  1953     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1954 		    NULL,
       
  1955 		    "xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead",
       
  1956 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1957 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1958 	return(-1);
       
  1959     }
       
  1960 
       
  1961     /* next is optional <xkms:TimeInstant/> node */
       
  1962     if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeTimeInstant, xmlSecXkmsNs)) {
       
  1963 	ret = xmlSecXkmsServerCtxTimeInstantNodeRead(ctx, cur);
       
  1964 	if(ret < 0) {
       
  1965     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1966 		        NULL,
       
  1967 			"xmlSecXkmsServerCtxTimeInstantNodeRead",
       
  1968 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1969 			XMLSEC_ERRORS_NO_MESSAGE);
       
  1970 	    return(-1);
       
  1971 	}
       
  1972 	cur = xmlSecGetNextElementNode(cur->next);
       
  1973     }
       
  1974 
       
  1975     /* check that there is nothing after the last node */
       
  1976     if(cur != NULL) {
       
  1977 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1978 		    NULL,
       
  1979 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  1980 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
  1981 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1982 	return(-1);
       
  1983     }
       
  1984     
       
  1985     return(0);
       
  1986 }
       
  1987 
       
  1988 /**
       
  1989  *  <xkms:KeyBindingAbstractType Id?>
       
  1990  *      <ds:KeyInfo>?
       
  1991  *      <xkms:KeyUsage>?
       
  1992  *      <xkms:KeyUsage>?
       
  1993  *      <xkms:KeyUsage>?
       
  1994  *      <xkms:UseKeyWith Application Identifier>*
       
  1995  *
       
  1996  * XML Schema:
       
  1997  *    <!-- KeyBindingAbstractType-->
       
  1998  *    <complexType name="KeyBindingAbstractType" abstract="true">
       
  1999  *       <sequence>
       
  2000  *          <element ref="ds:KeyInfo" minOccurs="0"/>
       
  2001  *          <element ref="xkms:KeyUsage" minOccurs="0" maxOccurs="3"/>
       
  2002  *          <element ref="xkms:UseKeyWith" minOccurs="0" 
       
  2003  *                   maxOccurs="unbounded"/>
       
  2004  *       </sequence>
       
  2005  *       <attribute name="Id" type="ID" use="optional"/>
       
  2006  *    </complexType>
       
  2007  *    <!-- /KeyBindingAbstractType-->
       
  2008  */
       
  2009 static int 
       
  2010 xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
       
  2011     xmlNodePtr cur;
       
  2012     int ret;
       
  2013     
       
  2014     xmlSecAssert2(ctx != NULL, -1);
       
  2015     xmlSecAssert2(node != NULL, -1);
       
  2016     xmlSecAssert2((*node) != NULL, -1);
       
  2017     
       
  2018     cur = (*node);
       
  2019     xmlSecAssert2(cur != NULL, -1);
       
  2020     
       
  2021     /* we don't care about Id attribute in this node */
       
  2022     cur = xmlSecGetNextElementNode(cur->children);
       
  2023     
       
  2024     /* first node is optional <dsig:KeyInfo/> node. for now we only remember pointer */
       
  2025     xmlSecAssert2(ctx->keyInfoNode == NULL, -1);
       
  2026     if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs)) {
       
  2027 	ctx->keyInfoNode = cur;
       
  2028 	cur = xmlSecGetNextElementNode(cur->next);
       
  2029     }
       
  2030     
       
  2031     /* next is zero or more <xkms:KeyUsage/> nodes */
       
  2032     ret = xmlSecQName2BitMaskNodesRead(gXmlSecXkmsKeyUsageInfo, &cur,
       
  2033 		    xmlSecNodeKeyUsage, xmlSecXkmsNs, 
       
  2034                     ((ctx->flags & XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_KEY_USAGE) != 0) ? 1 : 0,
       
  2035 		    &(ctx->keyInfoReadCtx.keyReq.keyUsage));
       
  2036     if(ret < 0) {
       
  2037     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2038 		    NULL,
       
  2039 		    "xmlSecQName2BitMaskNodesRead",
       
  2040 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2041 		    "name=%s",
       
  2042 		    xmlSecErrorsSafeString(xmlSecNodeKeyUsage));
       
  2043 	return(-1);
       
  2044     }
       
  2045     
       
  2046     /* next is zero or more <xkms:UseKeyWith/> nodes */
       
  2047     ret = xmlSecXkmsServerCtxUseKeyWithNodesRead(ctx, &cur);
       
  2048     if(ret < 0) {
       
  2049     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2050 		    NULL,
       
  2051 		    "xmlSecXkmsServerCtxUseKeyWithNodesRead",
       
  2052 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2053 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2054 	return(-1);
       
  2055     }
       
  2056 
       
  2057     (*node) = cur;
       
  2058     return(0);
       
  2059 }
       
  2060 
       
  2061 static int 
       
  2062 xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
       
  2063     xmlNodePtr cur;
       
  2064     int ret;
       
  2065 
       
  2066     xmlSecAssert2(ctx != NULL, -1);
       
  2067     xmlSecAssert2(node != NULL, -1);
       
  2068     xmlSecAssert2(key != NULL, -1);
       
  2069 
       
  2070     /* generate and add Id attribute */
       
  2071     ret = xmlSecGenerateAndAddID(node, xmlSecAttrId, ctx->idPrefix, ctx->idLen);
       
  2072     if(ret < 0) {
       
  2073 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2074 		    NULL,
       
  2075 		    "xmlSecGenerateAndAddID",
       
  2076 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2077 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2078 	return(-1);  	
       
  2079     }
       
  2080 
       
  2081     /* <dsig:KeyInfo/> node */
       
  2082     cur = xmlSecAddChild(node, xmlSecNodeKeyInfo, xmlSecDSigNs);
       
  2083     if(cur == NULL) {
       
  2084 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2085 		    NULL,
       
  2086 		    "xmlSecAddChild",
       
  2087 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2088 		    "node=%s",
       
  2089 		    xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
       
  2090 	return(-1);  	
       
  2091     }
       
  2092 
       
  2093     ret = xmlSecXkmsServerCtxKeyInfoNodeWrite(ctx, cur, key);
       
  2094     if(ret < 0) {
       
  2095 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2096 		    NULL,
       
  2097 		    "xmlSecXkmsServerCtxKeyInfoNodeWrite",
       
  2098 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2099 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2100 	return(-1);  	
       
  2101     }
       
  2102     
       
  2103     /* next is <xkms:KeyUsage/> node */
       
  2104     ret = xmlSecQName2BitMaskNodesWrite(gXmlSecXkmsKeyUsageInfo, node,
       
  2105 		    xmlSecNodeKeyUsage, xmlSecXkmsNs, 
       
  2106 		    key->usage);
       
  2107     if(ret < 0) {
       
  2108     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2109 		    NULL,
       
  2110 		    "xmlSecQName2BitMaskNodesWrite",
       
  2111 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2112 		    "name=%s",
       
  2113 		    xmlSecErrorsSafeString(xmlSecNodeKeyUsage));
       
  2114 	return(-1);
       
  2115     }
       
  2116 
       
  2117     /* and the last node is <xkms:UseKeyWith/> */
       
  2118     ret = xmlSecXkmsServerCtxUseKeyWithNodesWrite(ctx, node, key);
       
  2119     if(ret < 0) {
       
  2120     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2121 		    NULL,
       
  2122 		    "xmlSecXkmsServerCtxUseKeyWithNodesWrite",
       
  2123 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2124 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2125 	return(-1);
       
  2126     }
       
  2127     
       
  2128     return(0);
       
  2129 }
       
  2130 
       
  2131 static int 
       
  2132 xmlSecXkmsServerCtxKeyInfoNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
       
  2133     int ret;
       
  2134 
       
  2135     xmlSecAssert2(ctx != NULL, -1);
       
  2136     xmlSecAssert2(key != NULL, -1);
       
  2137     xmlSecAssert2(node != NULL, -1);
       
  2138 
       
  2139     /* add child nodes as requested in <xkms:RespondWith/> nodes */
       
  2140     ret = xmlSecXkmsRespondWithIdListWrite(&(ctx->respWithList), ctx, node);
       
  2141     if(ret < 0) {
       
  2142 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2143 		    NULL,
       
  2144 		    "xmlSecXkmsRespondWithIdListWrite",
       
  2145 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2146 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2147 	return(-1);  	
       
  2148     }
       
  2149 
       
  2150     ret = xmlSecKeyInfoNodeWrite(node, key, &(ctx->keyInfoWriteCtx));
       
  2151     if(ret < 0) {
       
  2152 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2153 		    NULL,
       
  2154 		    "xmlSecKeyInfoNodeWrite",
       
  2155 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2156 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2157 	return(-1);  	
       
  2158     }
       
  2159 
       
  2160     return(0);
       
  2161 }
       
  2162 
       
  2163 
       
  2164 /**
       
  2165  * XML Schema:
       
  2166  *    <!-- UseKeyWith -->
       
  2167  *    <element name="UseKeyWith" type="xkms:UseKeyWithType"/>
       
  2168  *    <complexType name="UseKeyWithType">
       
  2169  *      <attribute name="Application" type="anyURI" use="required"/>
       
  2170  *      <attribute name="Identifier" type="string" use="required"/>
       
  2171  *    </complexType>
       
  2172  *    <!-- /UseKeyWith -->
       
  2173  */
       
  2174 static int
       
  2175 xmlSecXkmsServerCtxUseKeyWithNodesRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
       
  2176     xmlSecPtrListPtr list;
       
  2177     xmlNodePtr cur;
       
  2178     xmlSecKeyUseWithPtr keyUseWith;
       
  2179     xmlChar* application;
       
  2180     xmlChar* identifier;
       
  2181     int ret;
       
  2182     
       
  2183     xmlSecAssert2(ctx != NULL, -1);
       
  2184     xmlSecAssert2(node != NULL, -1);
       
  2185 
       
  2186     list = &(ctx->keyInfoReadCtx.keyReq.keyUseWithList);
       
  2187     xmlSecAssert2(xmlSecPtrListGetSize(list) == 0, -1);
       
  2188 
       
  2189     cur = (*node);
       
  2190     while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeUseKeyWith, xmlSecXkmsNs)) {
       
  2191 	application = xmlGetProp(cur, xmlSecAttrApplication);
       
  2192 	if(application == NULL) {
       
  2193 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2194 		    	NULL,
       
  2195 			"xmlGetProp",
       
  2196 			XMLSEC_ERRORS_R_XML_FAILED,
       
  2197 			"name=%s;node=%s",
       
  2198 			xmlSecErrorsSafeString(xmlSecAttrApplication),
       
  2199 			xmlSecErrorsSafeString(cur->name));
       
  2200     	    return(-1);
       
  2201 	}
       
  2202 
       
  2203 	identifier = xmlGetProp(cur, xmlSecAttrIdentifier);
       
  2204 	if(identifier == NULL) {
       
  2205 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2206 		    	NULL,
       
  2207 			"xmlGetProp",
       
  2208 			XMLSEC_ERRORS_R_XML_FAILED,
       
  2209 			"name=%s;node=%s",
       
  2210 			xmlSecErrorsSafeString(xmlSecAttrIdentifier),
       
  2211 			xmlSecErrorsSafeString(cur->name));
       
  2212 	    xmlFree(application);
       
  2213     	    return(-1);
       
  2214 	}
       
  2215 	
       
  2216 	keyUseWith = xmlSecKeyUseWithCreate(application, identifier);
       
  2217 	if(keyUseWith == NULL) {
       
  2218 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2219 		    	NULL,
       
  2220 			"xmlSecKeyUseWithCreate",
       
  2221 		    	XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2222 			XMLSEC_ERRORS_NO_MESSAGE);
       
  2223 	    xmlFree(application);
       
  2224 	    xmlFree(identifier);
       
  2225     	    return(-1);
       
  2226 	}
       
  2227 	xmlFree(application);
       
  2228 	xmlFree(identifier);
       
  2229 	
       
  2230 	ret = xmlSecPtrListAdd(list, keyUseWith);
       
  2231 	if(ret < 0) {
       
  2232 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2233 		    	NULL,
       
  2234 			"xmlSecPtrListAdd",
       
  2235 		    	XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2236 			XMLSEC_ERRORS_NO_MESSAGE);
       
  2237 	    xmlSecKeyUseWithDestroy(keyUseWith);
       
  2238     	    return(-1);
       
  2239 	}
       
  2240 	
       
  2241 	cur = xmlSecGetNextElementNode(cur->next);
       
  2242     }
       
  2243 
       
  2244     (*node) = cur;    
       
  2245     return(0);
       
  2246 }
       
  2247 
       
  2248 static int 
       
  2249 xmlSecXkmsServerCtxUseKeyWithNodesWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
       
  2250     xmlSecAssert2(ctx != NULL, -1);
       
  2251     xmlSecAssert2(node != NULL, -1);
       
  2252     xmlSecAssert2(key != NULL, -1);
       
  2253 
       
  2254     return(0);
       
  2255 }
       
  2256 
       
  2257 
       
  2258 static int 
       
  2259 xmlSecXkmsServerCtxTimeInstantNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  2260     xmlSecAssert2(ctx != NULL, -1);
       
  2261     xmlSecAssert2(node != NULL, -1);
       
  2262 
       
  2263     return(0);
       
  2264 }
       
  2265 
       
  2266 /**
       
  2267  *  <xkms:ResultType Id Service Nonce? ResultMajor ResultMinor? RequestId?>
       
  2268  *      <ds:Signature>?
       
  2269  *      <xkms:MessageExtension>*
       
  2270  *      (<xkms:OpaqueClientData>
       
  2271  *          <xkms:OpaqueData>?
       
  2272  *      )?
       
  2273  *      <xkms:RequestSignatureValue>*
       
  2274  *
       
  2275  * XML Schema:
       
  2276  *    <!-- ResultType -->
       
  2277  *    <element name="Result" type="xkms:ResultType"/>
       
  2278  *    <complexType name="ResultType">
       
  2279  *       <complexContent>
       
  2280  *          <extension base="xkms:MessageAbstractType">
       
  2281  *             <sequence>
       
  2282  *                <element ref="xkms:RequestSignatureValue" minOccurs="0"/>
       
  2283  *	       </sequence>
       
  2284  *	       <attribute name="ResultMajor" type="QName" use="required"/>
       
  2285  *	       <attribute name="ResultMinor" type="QName" use="optional"/>
       
  2286  *	       <attribute name="RequestId" type="anyURI" use="optional"/>
       
  2287  *	    </extension>
       
  2288  *	 </complexContent>
       
  2289  *    </complexType>
       
  2290  *    <!-- /ResultType -->
       
  2291  */
       
  2292 static int 
       
  2293 xmlSecXkmsServerCtxResultTypeNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  2294     int ret;
       
  2295     
       
  2296     xmlSecAssert2(ctx != NULL, -1);
       
  2297     xmlSecAssert2(node != NULL, -1);
       
  2298 
       
  2299     /* generate and add Id attribute */
       
  2300     ret = xmlSecGenerateAndAddID(node, xmlSecAttrId, ctx->idPrefix, ctx->idLen);
       
  2301     if(ret < 0) {
       
  2302 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2303 		    NULL,
       
  2304 		    "xmlSecGenerateAndAddID",
       
  2305 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2306 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2307 	return(-1);  	
       
  2308     }
       
  2309 
       
  2310 
       
  2311     /* set Service atribute (required) */   
       
  2312     if((ctx->service == NULL) || (xmlSetProp(node, xmlSecAttrService, ctx->service) == NULL)) {
       
  2313 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2314 		    NULL,
       
  2315 		    "xmlSetProp",
       
  2316 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  2317 		    "name=%s,value=%s",
       
  2318 		    xmlSecErrorsSafeString(xmlSecAttrService),
       
  2319 		    xmlSecErrorsSafeString(ctx->service));
       
  2320 	return(-1);	
       
  2321     }
       
  2322     
       
  2323 
       
  2324     /* set RequestId atribute (optional) */   
       
  2325     if((ctx->id != NULL) && (xmlSetProp(node, xmlSecAttrRequestId, ctx->id) == NULL)) {
       
  2326 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2327 		    NULL,
       
  2328 		    "xmlSetProp",
       
  2329 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  2330 		    "name=%s,value=%s",
       
  2331 		    xmlSecErrorsSafeString(xmlSecAttrRequestId),
       
  2332 		    xmlSecErrorsSafeString(ctx->id));
       
  2333 	return(-1);	
       
  2334     }
       
  2335     
       
  2336     
       
  2337     /* set major code (required) */ 
       
  2338     ret = xmlSecQName2IntegerAttributeWrite(gXmlSecXkmsResultMajorInfo, node,
       
  2339 					     xmlSecAttrResultMajor, ctx->resultMajor);
       
  2340     if(ret < 0) {
       
  2341 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2342 		    NULL,
       
  2343 		    "xmlSecQName2IntegerAttributeWrite",
       
  2344 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2345 		    "name=%s,value=%d",
       
  2346 		    xmlSecErrorsSafeString(xmlSecAttrResultMajor),
       
  2347 		    ctx->resultMajor);
       
  2348 	return(-1);	
       
  2349     }
       
  2350 
       
  2351     /* set minor code (optional) */ 
       
  2352     if(ctx->resultMinor != xmlSecXkmsResultMinorNone) {
       
  2353         ret = xmlSecQName2IntegerAttributeWrite(gXmlSecXkmsMinorErrorInfo, node,
       
  2354 					     xmlSecAttrResultMinor, ctx->resultMinor);
       
  2355 	if(ret < 0) {
       
  2356 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2357 		        NULL,
       
  2358 			"xmlSecQName2IntegerAttributeWrite",
       
  2359 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2360 		        "name=%s,value=%d",
       
  2361 			xmlSecErrorsSafeString(xmlSecAttrResultMinor),
       
  2362 			ctx->resultMinor);
       
  2363 	    return(-1);	
       
  2364 	}
       
  2365     }
       
  2366 
       
  2367     
       
  2368 
       
  2369     /* <xkms:OpaqueClientData/>: An XKMS service SHOULD return the value of 
       
  2370      * the <OpaqueClientData> element unmodified in a request in a response 
       
  2371      * with status code Succes */
       
  2372     if((ctx->resultMajor == xmlSecXkmsResultMajorSuccess) && (ctx->opaqueClientDataNode != NULL)) {
       
  2373         xmlNodePtr copyNode;
       
  2374 
       
  2375 	copyNode = xmlDocCopyNode(ctx->opaqueClientDataNode, node->doc, 1);
       
  2376 	if(copyNode == NULL) {
       
  2377 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2378 		    	NULL,
       
  2379 			"xmlSetProp",
       
  2380 			XMLSEC_ERRORS_R_XML_FAILED,
       
  2381 			"name=%s",
       
  2382 			xmlSecErrorsSafeString(ctx->opaqueClientDataNode->name));
       
  2383 	    return(-1);
       
  2384 	}	
       
  2385 	
       
  2386 	if(xmlSecAddChildNode(node, copyNode) == NULL) {
       
  2387 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2388 		    	NULL,
       
  2389 			"xmlSecAddChildNode",
       
  2390 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2391 			"name=%s",
       
  2392 			xmlSecErrorsSafeString(copyNode->name));
       
  2393 	    return(-1);
       
  2394 	}
       
  2395     }
       
  2396 
       
  2397     ret = xmlSecXkmsServerCtxRequestSignatureValueNodeWrite(ctx, node);
       
  2398     if(ret < 0) {
       
  2399 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2400 		    NULL,
       
  2401 		    "xmlSecXkmsServerCtxRequestSignatureValueNodeWrite",
       
  2402 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2403 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2404 	return(-1);  	
       
  2405     }
       
  2406 
       
  2407     return(0);
       
  2408 }
       
  2409 
       
  2410 /** 
       
  2411  * A service SHOULD include the <RequestSignatureValue> element in a response 
       
  2412  * if the following conditions are satisfied and MUST NOT include the value 
       
  2413  * otherwise:
       
  2414  *
       
  2415  *
       
  2416  *  - The <ds:Signature> element was present in the corresponding request
       
  2417  *  - The service successfully verified the <ds:Signature> element in the 
       
  2418  *  corresponding request, and
       
  2419  *  - The ResponseMechanism RequestSignatureValue was specified.
       
  2420  *    
       
  2421  */
       
  2422 static int 
       
  2423 xmlSecXkmsServerCtxRequestSignatureValueNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  2424     xmlSecAssert2(ctx != NULL, -1);
       
  2425     xmlSecAssert2(node != NULL, -1);
       
  2426     
       
  2427     if((ctx->responseMechanismMask & XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_REQUEST_SIGNATURE_VALUE) == 0) {
       
  2428 	/* The ResponseMechanism RequestSignatureValue was not specified. */
       
  2429 	return(0);
       
  2430     }
       
  2431     
       
  2432     return(0);
       
  2433 }
       
  2434 
       
  2435 
       
  2436 /** 
       
  2437  *  
       
  2438  *  <xkms:UnverifiedKeyBindingType Id?>
       
  2439  *      <ds:KeyInfo>?
       
  2440  *      <xkms:KeyUsage>?
       
  2441  *      <xkms:KeyUsage>?
       
  2442  *      <xkms:KeyUsage>?
       
  2443  *      <xkms:UseKeyWith Application Identifier>*    
       
  2444  *      <xkms:ValidityInterval NotBefore NotOnOrAfter>?
       
  2445  *  
       
  2446  * XML Schema:
       
  2447  *
       
  2448  *    <!-- UnverifiedKeyBinding -->
       
  2449  *    <element name="UnverifiedKeyBinding" type="xkms:UnverifiedKeyBindingType"/>
       
  2450  *    <complexType name="UnverifiedKeyBindingType">
       
  2451  *       <complexContent>
       
  2452  *          <extension base="xkms:KeyBindingAbstractType">
       
  2453  *             <sequence>
       
  2454  *                 <element ref="xkms:ValidityInterval" minOccurs="0"/>
       
  2455  *             </sequence>
       
  2456  *          </extension>
       
  2457  *       </complexContent>
       
  2458  *    </complexType>
       
  2459  *    <!-- /UnverifiedKeyBinding -->
       
  2460  */
       
  2461 static int 
       
  2462 xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
       
  2463     int ret;
       
  2464 
       
  2465     xmlSecAssert2(ctx != NULL, -1);
       
  2466     xmlSecAssert2(key != NULL, -1);
       
  2467     xmlSecAssert2(node != NULL, -1);
       
  2468 
       
  2469     /* first write "parent" type */
       
  2470     ret = xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite(ctx, node, key);    
       
  2471     if(ret < 0) {
       
  2472 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2473 		    NULL,
       
  2474 		    "xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite",
       
  2475 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2476 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2477 	return(-1);  	
       
  2478     }
       
  2479     
       
  2480     /* <xkms:ValidityInterval/> node */
       
  2481     ret = xmlSecXkmsServerCtxValidityIntervalNodeWrite(ctx, node, key);    
       
  2482     if(ret < 0) {
       
  2483 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2484 		    NULL,
       
  2485 		    "xmlSecXkmsServerCtxValidityIntervalNodeWrite",
       
  2486 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2487 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2488 	return(-1);  	
       
  2489     }
       
  2490 
       
  2491     return(0);
       
  2492 }
       
  2493 
       
  2494 static int 
       
  2495 xmlSecXkmsServerCtxValidityIntervalNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
       
  2496     xmlSecAssert2(ctx != NULL, -1);
       
  2497     xmlSecAssert2(key != NULL, -1);
       
  2498     xmlSecAssert2(node != NULL, -1);
       
  2499     
       
  2500     return(0);
       
  2501 }
       
  2502 
       
  2503 /** 
       
  2504  *  <xkms:KeyBinding Id?>
       
  2505  *      <ds:KeyInfo>?
       
  2506  *      <xkms:KeyUsage>?
       
  2507  *      <xkms:KeyUsage>?
       
  2508  *      <xkms:KeyUsage>?
       
  2509  *      <xkms:UseKeyWith Application Identifier>*    
       
  2510  *      <xkms:ValidityInterval NotBefore NotOnOrAfter>?
       
  2511  *      <xkms:Status StatusValue>
       
  2512  *          (<xkms:ValidReason>?
       
  2513  *           <xkms:IndeterminateReason>?
       
  2514  *           <xkms:InvalidReason>?
       
  2515  *           )*
       
  2516  *
       
  2517  * XML Schema:
       
  2518  * 
       
  2519  *    <!-- KeyBinding -->   
       
  2520  *    <element name="KeyBinding" type="xkms:KeyBindingType"/>   
       
  2521  *    <complexType name="KeyBindingType">      
       
  2522  *        <complexContent>         
       
  2523  *            <extension base="xkms:UnverifiedKeyBindingType">            
       
  2524  *                <sequence>               
       
  2525  *                    <element ref="xkms:Status"/>
       
  2526  *                </sequence>
       
  2527  *            </extension>
       
  2528  *        </complexContent>
       
  2529  *    </complexType>
       
  2530  *    <!-- /KeyBinding -->
       
  2531  */
       
  2532 static int 
       
  2533 xmlSecXkmsServerCtxKeyBindingNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
       
  2534     int ret;
       
  2535 
       
  2536     xmlSecAssert2(ctx != NULL, -1);
       
  2537     xmlSecAssert2(key != NULL, -1);
       
  2538     xmlSecAssert2(node != NULL, -1);
       
  2539 
       
  2540     /* first write "parent" type */
       
  2541     ret = xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(ctx, node, key);    
       
  2542     if(ret < 0) {
       
  2543 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2544 		    NULL,
       
  2545 		    "xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite",
       
  2546 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2547 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2548 	return(-1);  	
       
  2549     }
       
  2550 
       
  2551     /* <xkms:Status/> node */
       
  2552     ret = xmlSecXkmsServerCtxKeyBindingStatusNodeWrite(ctx, node, key);    
       
  2553     if(ret < 0) {
       
  2554 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2555 		    NULL,
       
  2556 		    "xmlSecXkmsServerCtxKeyBindingStatusNodeWrite",
       
  2557 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2558 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2559 	return(-1);  	
       
  2560     }
       
  2561 
       
  2562     return(0);
       
  2563 }
       
  2564 
       
  2565 /**
       
  2566  *  <xkms:Status StatusValue>
       
  2567  *      (<xkms:ValidReason>?
       
  2568  *       <xkms:IndeterminateReason>?
       
  2569  *       <xkms:InvalidReason>?
       
  2570  *      )*
       
  2571  * 
       
  2572  * XML Schema:
       
  2573  *
       
  2574  *    <!-- Status -->   
       
  2575  *    <element name="Status" type="xkms:StatusType"/>
       
  2576  *    <complexType name="StatusType">
       
  2577  *       <sequence>
       
  2578  *          <element ref="xkms:ValidReason" minOccurs="0" 
       
  2579  *                maxOccurs="unbounded"/>
       
  2580  *          <element ref="xkms:IndeterminateReason" minOccurs="0" 
       
  2581  *                maxOccurs="unbounded"/>
       
  2582  *          <element ref="xkms:InvalidReason" minOccurs="0" 
       
  2583  *                maxOccurs="unbounded"/>
       
  2584  *       </sequence>
       
  2585  *       <attribute name="StatusValue" type="xkms:KeyBindingStatus" 
       
  2586  *             use="required"/>
       
  2587  *    </complexType>
       
  2588  *    <simpleType name="KeyBindingStatus">
       
  2589  *       <restriction base="QName">
       
  2590  *          <enumeration value="xkms:Valid"/>
       
  2591  *          <enumeration value="xkms:Invalid"/>
       
  2592  *          <enumeration value="xkms:Indeterminate"/>
       
  2593  *       </restriction>
       
  2594  *    </simpleType>
       
  2595  *    <!-- /Status -->
       
  2596  */
       
  2597 static int 
       
  2598 xmlSecXkmsServerCtxKeyBindingStatusNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
       
  2599     xmlNodePtr cur;
       
  2600     int ret;
       
  2601 
       
  2602     xmlSecAssert2(ctx != NULL, -1);
       
  2603     xmlSecAssert2(key != NULL, -1);
       
  2604     xmlSecAssert2(node != NULL, -1);
       
  2605 
       
  2606     cur = xmlSecAddChild(node, xmlSecNodeStatus, xmlSecXkmsNs);
       
  2607     if(cur == NULL) {
       
  2608 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2609 		    NULL,
       
  2610 		    "xmlSecAddChild",
       
  2611 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2612 		    "node=%s",
       
  2613 		    xmlSecErrorsSafeString(xmlSecNodeStatus));
       
  2614 	return(-1);  	
       
  2615     }
       
  2616 
       
  2617     /* if we are here then the key was validated */
       
  2618     ret = xmlSecQName2IntegerAttributeWrite(gXmlSecXkmsKeyBindingStatusInfo, cur, 
       
  2619 		    xmlSecAttrStatusValue, xmlSecXkmsKeyBindingStatusValid);
       
  2620     if(ret < 0) {
       
  2621 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2622 		    NULL,
       
  2623 		    "xmlSecQName2IntegerAttributeWrite",
       
  2624 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2625 		    "name=%s",
       
  2626 		    xmlSecErrorsSafeString(xmlSecAttrStatusValue));
       
  2627 	return(-1);	
       
  2628     }
       
  2629     
       
  2630     return(0);
       
  2631 }
       
  2632 
       
  2633 /************************************************************************
       
  2634  *
       
  2635  * xmlSecXkmsServerCtx list
       
  2636  *
       
  2637  ************************************************************************/ 
       
  2638 static xmlSecPtrListKlass xmlSecXkmsServerCtxPtrListKlass = {
       
  2639     BAD_CAST "xkms-server-ctx-list",
       
  2640     NULL, 								/* xmlSecPtrDuplicateItemMethod duplicateItem; */
       
  2641     (xmlSecPtrDestroyItemMethod)xmlSecXkmsServerCtxDestroy,	        /* xmlSecPtrDestroyItemMethod destroyItem; */
       
  2642     (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerCtxDebugDump,	        /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
       
  2643     (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerCtxDebugXmlDump,	/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
       
  2644 };
       
  2645 EXPORT_C
       
  2646 
       
  2647 xmlSecPtrListId	
       
  2648 xmlSecXkmsServerCtxPtrListGetKlass(void) {
       
  2649     return(&xmlSecXkmsServerCtxPtrListKlass);
       
  2650 }
       
  2651 
       
  2652 
       
  2653 /**************************************************************************
       
  2654  *
       
  2655  * Global xmlSecXkmsRespondWithIds list functions
       
  2656  *
       
  2657  *************************************************************************/
       
  2658 static xmlSecPtrList xmlSecAllXkmsRespondWithIds;
       
  2659 
       
  2660 
       
  2661 /** 
       
  2662  * xmlSecXkmsRespondWithIdsGet:
       
  2663  *
       
  2664  * Gets global registered RespondWith klasses list.
       
  2665  * 
       
  2666  * Returns the pointer to list of all registered RespondWith klasses.
       
  2667  */
       
  2668 EXPORT_C
       
  2669 xmlSecPtrListPtr
       
  2670 xmlSecXkmsRespondWithIdsGet(void) {
       
  2671     return(&xmlSecAllXkmsRespondWithIds);
       
  2672 }
       
  2673 
       
  2674 /** 
       
  2675  * xmlSecXkmsRespondWithIdsInit:
       
  2676  *
       
  2677  * Initializes the RespondWith klasses. This function is called from the 
       
  2678  * #xmlSecInit function and the application should not call it directly.
       
  2679  *
       
  2680  * Returns 0 on success or a negative value if an error occurs.
       
  2681  */
       
  2682 EXPORT_C
       
  2683 int 
       
  2684 xmlSecXkmsRespondWithIdsInit(void) {
       
  2685     int ret;
       
  2686     
       
  2687     ret = xmlSecPtrListInitialize(xmlSecXkmsRespondWithIdsGet(), xmlSecXkmsRespondWithIdListId);
       
  2688     if(ret < 0) {
       
  2689 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2690 		    NULL,
       
  2691 		    "xmlSecPtrListPtrInitialize",
       
  2692 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2693 		    "xmlSecXkmsRespondWithIdListId");
       
  2694         return(-1);
       
  2695     }
       
  2696     
       
  2697     ret = xmlSecXkmsRespondWithIdsRegisterDefault();
       
  2698     if(ret < 0) {
       
  2699 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2700 		    NULL,
       
  2701 		    "xmlSecXkmsRespondWithIdsRegisterDefault",
       
  2702 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2703 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2704         return(-1);
       
  2705     }
       
  2706     
       
  2707     return(0);
       
  2708 }
       
  2709 
       
  2710 /**
       
  2711  * xmlSecXkmsRespondWithIdsShutdown:
       
  2712  * 
       
  2713  * Shuts down the keys data klasses. This function is called from the 
       
  2714  * #xmlSecShutdown function and the application should not call it directly.
       
  2715  */
       
  2716 EXPORT_C
       
  2717 void
       
  2718 xmlSecXkmsRespondWithIdsShutdown(void) {
       
  2719     xmlSecPtrListFinalize(xmlSecXkmsRespondWithIdsGet());
       
  2720 }
       
  2721 
       
  2722 /** 
       
  2723  * xmlSecXkmsRespondWithIdsRegister:
       
  2724  * @id:		the RespondWith klass.
       
  2725  *
       
  2726  * Registers @id in the global list of RespondWith klasses.
       
  2727  *
       
  2728  * Returns 0 on success or a negative value if an error occurs.
       
  2729  */
       
  2730 EXPORT_C
       
  2731 int 
       
  2732 xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithId id) {
       
  2733     int ret;
       
  2734         
       
  2735     xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
       
  2736     
       
  2737     ret = xmlSecPtrListAdd(xmlSecXkmsRespondWithIdsGet(), (xmlSecPtr)id);
       
  2738     if(ret < 0) {
       
  2739 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2740 		    NULL,
       
  2741 		    "xmlSecPtrListAdd",
       
  2742 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2743 		    "RespondWith=%s",
       
  2744 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)));
       
  2745         return(-1);
       
  2746     }
       
  2747     
       
  2748     return(0);    
       
  2749 }
       
  2750 
       
  2751 /**
       
  2752  * xmlSecXkmsRespondWithIdsRegisterDefault:
       
  2753  *
       
  2754  * Registers default (implemented by XML Security Library)
       
  2755  * RespondWith klasses: KeyName, KeyValue,...
       
  2756  *
       
  2757  * Returns 0 on success or a negative value if an error occurs.
       
  2758  */
       
  2759 EXPORT_C
       
  2760 int 
       
  2761 xmlSecXkmsRespondWithIdsRegisterDefault(void) {
       
  2762     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithKeyNameId) < 0) {
       
  2763 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2764 		    NULL,
       
  2765 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2766 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2767 		    "name=%s",
       
  2768 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithKeyNameId)));
       
  2769 	return(-1);
       
  2770     }
       
  2771 
       
  2772     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithKeyValueId) < 0) {
       
  2773 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2774 		    NULL,
       
  2775 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2776 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2777 		    "name=%s",
       
  2778 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithKeyValueId)));
       
  2779 	return(-1);
       
  2780     }
       
  2781 
       
  2782     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithPrivateKeyId) < 0) {
       
  2783 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2784 		    NULL,
       
  2785 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2786 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2787 		    "name=%s",
       
  2788 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithPrivateKeyId)));
       
  2789 	return(-1);
       
  2790     }
       
  2791 
       
  2792     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithRetrievalMethodId) < 0) {
       
  2793 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2794 		    NULL,
       
  2795 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2796 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2797 		    "name=%s",
       
  2798 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithRetrievalMethodId)));
       
  2799 	return(-1);
       
  2800     }
       
  2801 
       
  2802     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithX509CertId) < 0) {
       
  2803 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2804 		    NULL,
       
  2805 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2806 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2807 		    "name=%s",
       
  2808 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithX509CertId)));
       
  2809 	return(-1);
       
  2810     }
       
  2811 
       
  2812     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithX509ChainId) < 0) {
       
  2813 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2814 		    NULL,
       
  2815 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2816 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2817 		    "name=%s",
       
  2818 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithX509ChainId)));
       
  2819 	return(-1);
       
  2820     }
       
  2821 
       
  2822     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithX509CRLId) < 0) {
       
  2823 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2824 		    NULL,
       
  2825 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2826 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2827 		    "name=%s",
       
  2828 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithX509CRLId)));
       
  2829 	return(-1);
       
  2830     }
       
  2831 
       
  2832     /*
       
  2833     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithPGPId) < 0) {
       
  2834 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2835 		    NULL,
       
  2836 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2837 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2838 		    "name=%s",
       
  2839 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithPGPId)));
       
  2840 	return(-1);
       
  2841     }
       
  2842 
       
  2843     if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithSPKIId) < 0) {
       
  2844 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2845 		    NULL,
       
  2846 		    "xmlSecXkmsRespondWithIdsRegister",	    
       
  2847 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2848 		    "name=%s",
       
  2849 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithSPKIId)));
       
  2850 	return(-1);
       
  2851     }
       
  2852     */
       
  2853     return(0);
       
  2854 }
       
  2855 
       
  2856 
       
  2857 /************************************************************************
       
  2858  *
       
  2859  * XKMS RespondWith Klass
       
  2860  *
       
  2861  ************************************************************************/ 
       
  2862 /**
       
  2863  * xmlSecXkmsRespondWithNodeRead:
       
  2864  * @id:		the RespondWith class.
       
  2865  * @ctx:	the XKMS request processing context.
       
  2866  * @node:	the pointer to <xkms:RespondWith/> node.
       
  2867  *
       
  2868  * Reads the content of the <xkms:RespondWith/> @node.
       
  2869  *
       
  2870  * Returns 0 on success or a negative value if an error occurs.
       
  2871  */
       
  2872 EXPORT_C
       
  2873 int  
       
  2874 xmlSecXkmsRespondWithNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  2875 			      xmlNodePtr node) {
       
  2876     xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
       
  2877     xmlSecAssert2(ctx != NULL, -1);
       
  2878     xmlSecAssert2(node != NULL, -1);
       
  2879 
       
  2880     if(id->readNode != NULL) {
       
  2881 	return((id->readNode)(id, ctx, node));
       
  2882     }
       
  2883     return(0);
       
  2884 }
       
  2885 
       
  2886 /**
       
  2887  * xmlSecXkmsRespondWithNodeWrite:
       
  2888  * @id:		the RespondWith class.
       
  2889  * @ctx:	the XKMS request processing context.
       
  2890  * @node:	the pointer to <xkms:RespondWith/> node.
       
  2891  *
       
  2892  * Writes the content of the <xkms:RespondWith/> @node.
       
  2893  *
       
  2894  * Returns 0 on success or a negative value if an error occurs.
       
  2895  */
       
  2896 EXPORT_C
       
  2897 int 
       
  2898 xmlSecXkmsRespondWithNodeWrite(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  2899 			     xmlNodePtr node) {
       
  2900     xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
       
  2901     xmlSecAssert2(ctx != NULL, -1);
       
  2902     xmlSecAssert2(node != NULL, -1);
       
  2903 
       
  2904     if(id->writeNode != NULL) {
       
  2905 	return((id->writeNode)(id, ctx, node));
       
  2906     }
       
  2907     return(0);
       
  2908 }
       
  2909 
       
  2910 /**
       
  2911  * xmlSecXkmsRespondWithDebugDump:
       
  2912  * @id:		the RespondWith class.
       
  2913  * @output:	the output file.
       
  2914  *
       
  2915  * Writes debug information about @id into the @output.
       
  2916  */
       
  2917 EXPORT_C
       
  2918 void 
       
  2919 xmlSecXkmsRespondWithDebugDump(xmlSecXkmsRespondWithId id, FILE* output) {
       
  2920     xmlSecAssert(id != xmlSecXkmsRespondWithIdUnknown);
       
  2921     xmlSecAssert(output != NULL);
       
  2922 
       
  2923     fprintf(output, "=== RespondWith: \"%s\" (href=\"%s\")\n", 
       
  2924         xmlSecErrorsSafeString(id->valueName),
       
  2925         xmlSecErrorsSafeString(id->valueNs));
       
  2926 }
       
  2927 
       
  2928 /**
       
  2929  * xmlSecXkmsRespondWithDebugXmlDump:
       
  2930  * @id:		the RespondWith class.
       
  2931  * @output:	the output file.
       
  2932  *
       
  2933  * Writes debug information about @id into the @output in XML format.
       
  2934  */
       
  2935 EXPORT_C
       
  2936 void 
       
  2937 xmlSecXkmsRespondWithDebugXmlDump(xmlSecXkmsRespondWithId id, FILE* output) {
       
  2938     xmlSecAssert(id != xmlSecXkmsRespondWithIdUnknown);
       
  2939     xmlSecAssert(output != NULL);
       
  2940 
       
  2941     fprintf(output, "<RespondWith href=\"%s\">%s</RespondWith>\n", 
       
  2942         xmlSecErrorsSafeString(id->valueNs),
       
  2943         xmlSecErrorsSafeString(id->valueName));
       
  2944 }
       
  2945 EXPORT_C
       
  2946 
       
  2947 int 
       
  2948 xmlSecXkmsRespondWithDefaultNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  2949 			    xmlNodePtr node) {
       
  2950     int ret;
       
  2951 
       
  2952     xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
       
  2953     xmlSecAssert2(ctx != NULL, -1);
       
  2954     xmlSecAssert2(node != NULL, -1);
       
  2955 
       
  2956     ret = xmlSecXkmsRespondWithIdListFind(&(ctx->respWithList), id);
       
  2957     if(ret < 0) {
       
  2958 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2959 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  2960 		    "xmlSecXkmsRespondWithIdListFind",
       
  2961 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2962 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2963 	return(-1);  	
       
  2964     } else if(ret > 0) {
       
  2965 	/* do nothing, we already have it in the list */
       
  2966 	return(0);
       
  2967     }    
       
  2968     
       
  2969     ret = xmlSecPtrListAdd(&(ctx->respWithList), id);
       
  2970     if(ret < 0) {
       
  2971 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2972 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  2973 		    "xmlSecPtrListAdd",
       
  2974 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2975 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2976 	return(-1);  	
       
  2977     }
       
  2978 
       
  2979     return(0);
       
  2980 }
       
  2981 EXPORT_C
       
  2982 
       
  2983 int  
       
  2984 xmlSecXkmsRespondWithDefaultNodeWrite(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  2985 			    xmlNodePtr node) {
       
  2986     xmlNodePtr cur;
       
  2987 
       
  2988     xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
       
  2989     xmlSecAssert2(id->nodeName != NULL, -1);
       
  2990     xmlSecAssert2(ctx != NULL, -1);
       
  2991     xmlSecAssert2(node != NULL, -1);
       
  2992 
       
  2993     cur = xmlSecAddChild(node, id->nodeName, id->nodeNs);
       
  2994     if(cur == NULL) {
       
  2995 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2996 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  2997 		    "xmlSecAddChild",
       
  2998 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2999 		    "node=%s",
       
  3000 		    xmlSecErrorsSafeString(id->nodeName));
       
  3001 	return(-1);  	
       
  3002     }
       
  3003 
       
  3004     return(0);
       
  3005 }
       
  3006 
       
  3007 /************************************************************************
       
  3008  *
       
  3009  * XKMS RespondWith Klass List
       
  3010  *
       
  3011  ************************************************************************/ 
       
  3012 static xmlSecPtrListKlass xmlSecXkmsRespondWithIdListKlass = {
       
  3013     BAD_CAST "respond-with-ids-list",
       
  3014     NULL, 								/* xmlSecPtrDuplicateItemMethod duplicateItem; */
       
  3015     NULL,								/* xmlSecPtrDestroyItemMethod destroyItem; */
       
  3016     (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsRespondWithDebugDump,	/* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
       
  3017     (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsRespondWithDebugXmlDump,	/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
       
  3018 };
       
  3019 EXPORT_C
       
  3020 
       
  3021 xmlSecPtrListId	
       
  3022 xmlSecXkmsRespondWithIdListGetKlass(void) {
       
  3023     return(&xmlSecXkmsRespondWithIdListKlass);
       
  3024 }
       
  3025 EXPORT_C
       
  3026 
       
  3027 int 
       
  3028 xmlSecXkmsRespondWithIdListFind(xmlSecPtrListPtr list, xmlSecXkmsRespondWithId id) {
       
  3029     xmlSecSize i, size;
       
  3030     
       
  3031     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsRespondWithIdListId), -1);
       
  3032     xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
       
  3033     
       
  3034     size = xmlSecPtrListGetSize(list);
       
  3035     for(i = 0; i < size; ++i) {
       
  3036 	if((xmlSecXkmsRespondWithId)xmlSecPtrListGetItem(list, i) == id) {
       
  3037 	    return(1);
       
  3038 	}
       
  3039     }
       
  3040     return(0);
       
  3041 }
       
  3042 EXPORT_C
       
  3043 
       
  3044 xmlSecXkmsRespondWithId 
       
  3045 xmlSecXkmsRespondWithIdListFindByNodeValue(xmlSecPtrListPtr list, xmlNodePtr node) {
       
  3046     xmlSecXkmsRespondWithId result = xmlSecXkmsRespondWithIdUnknown;
       
  3047     xmlSecXkmsRespondWithId id;
       
  3048     xmlChar* content;
       
  3049     xmlChar* qnameLocalPart = NULL;
       
  3050     xmlChar* qnamePrefix = NULL;
       
  3051     const xmlChar* qnameHref;
       
  3052     xmlNsPtr ns;
       
  3053     xmlSecSize i, size;
       
  3054     
       
  3055     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsRespondWithIdListId), xmlSecXkmsRespondWithIdUnknown);
       
  3056     xmlSecAssert2(node != NULL, xmlSecXkmsRespondWithIdUnknown);
       
  3057 
       
  3058     content = xmlNodeGetContent(node);
       
  3059     if(content == NULL) {
       
  3060 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3061                     NULL,
       
  3062 		    "xmlNodeGetContent",
       
  3063 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  3064 		    "node=%s",
       
  3065 		    xmlSecErrorsSafeString(node->name));
       
  3066 	return(xmlSecXkmsRespondWithIdUnknown);  	
       
  3067     }
       
  3068 
       
  3069     qnameLocalPart = (xmlChar*)xmlStrchr(content, ':');
       
  3070     if(qnameLocalPart != NULL) {
       
  3071         qnamePrefix = content;
       
  3072         *(qnameLocalPart++) = '\0';
       
  3073     } else {
       
  3074         qnamePrefix = NULL;
       
  3075         qnameLocalPart = content;
       
  3076     }
       
  3077     
       
  3078     /* search namespace href */
       
  3079     ns = xmlSearchNs(node->doc, node, qnamePrefix);
       
  3080     if((ns == NULL) && (qnamePrefix != NULL)) {
       
  3081 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3082 		    NULL,
       
  3083 		    "xmlSearchNs",
       
  3084 	    	    XMLSEC_ERRORS_R_XML_FAILED,
       
  3085 		    "node=%s,qnamePrefix=%s",
       
  3086 		    xmlSecErrorsSafeString(node->name),
       
  3087                     xmlSecErrorsSafeString(qnamePrefix));
       
  3088         xmlFree(content);
       
  3089 	return(xmlSecXkmsRespondWithIdUnknown);	
       
  3090     }
       
  3091     qnameHref = (ns != NULL) ? ns->href : BAD_CAST NULL;
       
  3092 
       
  3093     size = xmlSecPtrListGetSize(list);
       
  3094     for(i = 0; i < size; ++i) {
       
  3095 	id = (xmlSecXkmsRespondWithId)xmlSecPtrListGetItem(list, i);
       
  3096 	if((id !=  xmlSecXkmsRespondWithIdUnknown) && 
       
  3097                 xmlStrEqual(id->valueName, qnameLocalPart) &&
       
  3098                 xmlStrEqual(id->valueNs, qnameHref)) {
       
  3099 	    result = id;
       
  3100             break;
       
  3101 	}
       
  3102     }
       
  3103     
       
  3104     xmlFree(content);
       
  3105     return(result);    
       
  3106 }
       
  3107 EXPORT_C
       
  3108 
       
  3109 int 
       
  3110 xmlSecXkmsRespondWithIdListWrite(xmlSecPtrListPtr list, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  3111     xmlSecXkmsRespondWithId id;
       
  3112     xmlSecSize i, size;
       
  3113     int ret;
       
  3114 
       
  3115     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsRespondWithIdListId), -1);
       
  3116     xmlSecAssert2(ctx != NULL, -1);
       
  3117     xmlSecAssert2(node != NULL, -1);
       
  3118 
       
  3119     size = xmlSecPtrListGetSize(list);
       
  3120     for(i = 0; i < size; ++i) {
       
  3121 	id = (xmlSecXkmsRespondWithId)xmlSecPtrListGetItem(list, i);
       
  3122 	if(id !=  xmlSecXkmsRespondWithIdUnknown) {
       
  3123 	    ret = xmlSecXkmsRespondWithNodeWrite(id, ctx, node);
       
  3124 	    if(ret < 0) {
       
  3125 		xmlSecError(XMLSEC_ERRORS_HERE,
       
  3126 			    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  3127 			    "xmlSecXkmsRespondWithNodeWrite",
       
  3128 		    	    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3129 			    XMLSEC_ERRORS_NO_MESSAGE);
       
  3130 		return(-1);
       
  3131 	    }
       
  3132 	}
       
  3133     }
       
  3134 
       
  3135     return(0);
       
  3136 }
       
  3137 
       
  3138 /******************************************************************** 
       
  3139  *
       
  3140  * XML Sec Library RespondWith Ids
       
  3141  *
       
  3142  *******************************************************************/
       
  3143 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithKeyNameKlass = {
       
  3144     xmlSecRespondWithKeyName,			/* const xmlChar* valueName; */
       
  3145     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3146     xmlSecNodeKeyName,				/* const xmlChar* nodeName; */
       
  3147     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3148     xmlSecXkmsRespondWithDefaultNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3149     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3150     NULL,                                       /* void* reserved1; */
       
  3151     NULL                                        /* void* reserved2; */
       
  3152 };
       
  3153 
       
  3154 /**
       
  3155  * xmlSecXkmsRespondWithKeyNameGetKlass:
       
  3156  *
       
  3157  * The respond with KeyName klass.
       
  3158  *
       
  3159  * Returns respond with KeyName klass.
       
  3160  */
       
  3161 EXPORT_C 
       
  3162 xmlSecXkmsRespondWithId	
       
  3163 xmlSecXkmsRespondWithKeyNameGetKlass(void) {
       
  3164     return(&xmlSecXkmsRespondWithKeyNameKlass);
       
  3165 }
       
  3166 
       
  3167 
       
  3168 
       
  3169 static  int  		xmlSecXkmsRespondWithKeyValueNodeRead	(xmlSecXkmsRespondWithId id,
       
  3170 								 xmlSecXkmsServerCtxPtr ctx,
       
  3171 								 xmlNodePtr node);
       
  3172 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithKeyValueKlass = {
       
  3173     xmlSecRespondWithKeyValue,			/* const xmlChar* valueName; */
       
  3174     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3175     xmlSecNodeKeyValue,				/* const xmlChar* nodeName; */
       
  3176     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3177     xmlSecXkmsRespondWithKeyValueNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3178     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3179     NULL,                                       /* void* reserved1; */
       
  3180     NULL                                        /* void* reserved2; */
       
  3181 };
       
  3182 
       
  3183 /**
       
  3184  * xmlSecXkmsRespondWithKeyValueGetKlass:
       
  3185  *
       
  3186  * The respond with KeyValue klass.
       
  3187  *
       
  3188  * Returns respond with KeyValue klass.
       
  3189  */
       
  3190 EXPORT_C 
       
  3191 xmlSecXkmsRespondWithId	
       
  3192 xmlSecXkmsRespondWithKeyValueGetKlass(void) {
       
  3193     return(&xmlSecXkmsRespondWithKeyValueKlass);
       
  3194 }
       
  3195 
       
  3196 static  int  
       
  3197 xmlSecXkmsRespondWithKeyValueNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  3198 				      xmlNodePtr node) {
       
  3199     int ret;
       
  3200 
       
  3201     xmlSecAssert2(id == xmlSecXkmsRespondWithKeyValueId, -1);
       
  3202     xmlSecAssert2(ctx != NULL, -1);
       
  3203     xmlSecAssert2(node != NULL, -1);
       
  3204 
       
  3205     /* do usual stuff */
       
  3206     ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
       
  3207     if(ret < 0) {
       
  3208 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3209 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  3210 		    "xmlSecXkmsRespondWithDefaultNodeRead",
       
  3211 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3212 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  3213 	return(-1);  	
       
  3214     }
       
  3215     
       
  3216     /* and now set some parameters in the ctx to look for a public or private 
       
  3217      * key and to write a public key
       
  3218      */
       
  3219     ctx->keyInfoReadCtx.keyReq.keyType  |= (xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
       
  3220     ctx->keyInfoWriteCtx.keyReq.keyType |= xmlSecKeyDataTypePublic;
       
  3221 
       
  3222     return(0);
       
  3223 }
       
  3224 
       
  3225 static  int  		xmlSecXkmsRespondWithPrivateKeyNodeRead	(xmlSecXkmsRespondWithId id,
       
  3226 								 xmlSecXkmsServerCtxPtr ctx,
       
  3227 								 xmlNodePtr node);
       
  3228 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithPrivateKeyKlass = {
       
  3229     xmlSecRespondWithPrivateKey,		/* const xmlChar* valueName; */
       
  3230     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3231     xmlSecNodeKeyValue,				/* const xmlChar* nodeName; */
       
  3232     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3233     xmlSecXkmsRespondWithPrivateKeyNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3234     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3235     NULL,                                       /* void* reserved1; */
       
  3236     NULL                                        /* void* reserved2; */
       
  3237 };
       
  3238 
       
  3239 /**
       
  3240  * xmlSecXkmsRespondWithPrivateKeyGetKlass:
       
  3241  *
       
  3242  * The respond with PrivateKey klass.
       
  3243  *
       
  3244  * Returns respond with PrivateKey klass.
       
  3245  */
       
  3246 EXPORT_C 
       
  3247 xmlSecXkmsRespondWithId	
       
  3248 xmlSecXkmsRespondWithPrivateKeyGetKlass(void) {
       
  3249     return(&xmlSecXkmsRespondWithPrivateKeyKlass);
       
  3250 }
       
  3251 
       
  3252 static  int  
       
  3253 xmlSecXkmsRespondWithPrivateKeyNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  3254 				      xmlNodePtr node) {
       
  3255     int ret;
       
  3256 
       
  3257     xmlSecAssert2(id == xmlSecXkmsRespondWithPrivateKeyId, -1);
       
  3258     xmlSecAssert2(ctx != NULL, -1);
       
  3259     xmlSecAssert2(node != NULL, -1);
       
  3260 
       
  3261     /* do usual stuff */
       
  3262     ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
       
  3263     if(ret < 0) {
       
  3264 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3265 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  3266 		    "xmlSecXkmsRespondWithDefaultNodeRead",
       
  3267 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3268 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  3269 	return(-1);  	
       
  3270     }
       
  3271     
       
  3272     /* and now set some parameters in the ctx to look for a private 
       
  3273      * key and to write a private key
       
  3274      */
       
  3275     ctx->keyInfoReadCtx.keyReq.keyType  |= xmlSecKeyDataTypePrivate;
       
  3276     ctx->keyInfoWriteCtx.keyReq.keyType |= xmlSecKeyDataTypePrivate;
       
  3277 
       
  3278     return(0);
       
  3279 }
       
  3280 
       
  3281 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithRetrievalMethodKlass = {
       
  3282     xmlSecRespondWithRetrievalMethod,		/* const xmlChar* valueName; */
       
  3283     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3284     xmlSecNodeRetrievalMethod,			/* const xmlChar* nodeName; */
       
  3285     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3286     xmlSecXkmsRespondWithDefaultNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3287     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3288     NULL,                                       /* void* reserved1; */
       
  3289     NULL                                        /* void* reserved2; */
       
  3290 };
       
  3291 
       
  3292 /**
       
  3293  * xmlSecXkmsRespondWithRetrievalMethodGetKlass:
       
  3294  *
       
  3295  * The respond with RetrievalMethod klass.
       
  3296  *
       
  3297  * Returns respond with RetrievalMethod klass.
       
  3298  */
       
  3299 EXPORT_C 
       
  3300 xmlSecXkmsRespondWithId	
       
  3301 xmlSecXkmsRespondWithRetrievalMethodGetKlass(void) {
       
  3302     return(&xmlSecXkmsRespondWithRetrievalMethodKlass);
       
  3303 }
       
  3304 
       
  3305 
       
  3306 
       
  3307 static  int  		xmlSecXkmsRespondWithX509CertNodeRead	(xmlSecXkmsRespondWithId id,
       
  3308 								 xmlSecXkmsServerCtxPtr ctx,
       
  3309 								 xmlNodePtr node);
       
  3310 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithX509CertKlass = {
       
  3311     xmlSecRespondWithX509Cert,			/* const xmlChar* valueName; */
       
  3312     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3313     xmlSecNodeX509Data,				/* const xmlChar* nodeName; */
       
  3314     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3315     xmlSecXkmsRespondWithX509CertNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3316     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3317     NULL,                                       /* void* reserved1; */
       
  3318     NULL                                        /* void* reserved2; */
       
  3319 };
       
  3320 
       
  3321 /**
       
  3322  * xmlSecXkmsRespondWithX509CertGetKlass:
       
  3323  *
       
  3324  * The respond with X509Cert klass.
       
  3325  *
       
  3326  * Returns respond with X509Cert klass.
       
  3327  */
       
  3328 EXPORT_C 
       
  3329 xmlSecXkmsRespondWithId	
       
  3330 xmlSecXkmsRespondWithX509CertGetKlass(void) {
       
  3331     return(&xmlSecXkmsRespondWithX509CertKlass);
       
  3332 }
       
  3333 
       
  3334 static  int  
       
  3335 xmlSecXkmsRespondWithX509CertNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  3336 				      xmlNodePtr node) {
       
  3337     int ret;
       
  3338 
       
  3339     xmlSecAssert2(id == xmlSecXkmsRespondWithX509CertId, -1);
       
  3340     xmlSecAssert2(ctx != NULL, -1);
       
  3341     xmlSecAssert2(node != NULL, -1);
       
  3342 
       
  3343     /* do usual stuff */
       
  3344     ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
       
  3345     if(ret < 0) {
       
  3346 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3347 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  3348 		    "xmlSecXkmsRespondWithDefaultNodeRead",
       
  3349 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3350 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  3351 	return(-1);  	
       
  3352     }
       
  3353     
       
  3354     return(0);
       
  3355 }
       
  3356 
       
  3357 static  int  		xmlSecXkmsRespondWithX509ChainNodeRead	(xmlSecXkmsRespondWithId id,
       
  3358 								 xmlSecXkmsServerCtxPtr ctx,
       
  3359 								 xmlNodePtr node);
       
  3360 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithX509ChainKlass = {
       
  3361     xmlSecRespondWithX509Chain,			/* const xmlChar* valueName; */
       
  3362     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3363     xmlSecNodeX509Data,				/* const xmlChar* nodeName; */
       
  3364     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3365     xmlSecXkmsRespondWithX509ChainNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3366     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3367     NULL,                                       /* void* reserved1; */
       
  3368     NULL                                        /* void* reserved2; */
       
  3369 };
       
  3370 
       
  3371 /**
       
  3372  * xmlSecXkmsRespondWithX509ChainGetKlass:
       
  3373  *
       
  3374  * The respond with X509Chain klass.
       
  3375  *
       
  3376  * Returns respond with X509Chain klass.
       
  3377  */
       
  3378 EXPORT_C 
       
  3379 xmlSecXkmsRespondWithId	
       
  3380 xmlSecXkmsRespondWithX509ChainGetKlass(void) {
       
  3381     return(&xmlSecXkmsRespondWithX509ChainKlass);
       
  3382 }
       
  3383 
       
  3384 static  int  
       
  3385 xmlSecXkmsRespondWithX509ChainNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  3386 				      xmlNodePtr node) {
       
  3387     int ret;
       
  3388 
       
  3389     xmlSecAssert2(id == xmlSecXkmsRespondWithX509ChainId, -1);
       
  3390     xmlSecAssert2(ctx != NULL, -1);
       
  3391     xmlSecAssert2(node != NULL, -1);
       
  3392 
       
  3393     /* do usual stuff */
       
  3394     ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
       
  3395     if(ret < 0) {
       
  3396 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3397 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  3398 		    "xmlSecXkmsRespondWithDefaultNodeRead",
       
  3399 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3400 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  3401 	return(-1);  	
       
  3402     }
       
  3403     
       
  3404     return(0);
       
  3405 }
       
  3406 
       
  3407 static  int  		xmlSecXkmsRespondWithX509CRLNodeRead	(xmlSecXkmsRespondWithId id,
       
  3408 								 xmlSecXkmsServerCtxPtr ctx,
       
  3409 								 xmlNodePtr node);
       
  3410 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithX509CRLKlass = {
       
  3411     xmlSecRespondWithX509CRL,			/* const xmlChar* valueName; */
       
  3412     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3413     xmlSecNodeX509Data,				/* const xmlChar* nodeName; */
       
  3414     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3415     xmlSecXkmsRespondWithX509CRLNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3416     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3417     NULL,                                       /* void* reserved1; */
       
  3418     NULL                                        /* void* reserved2; */
       
  3419 };
       
  3420 
       
  3421 /**
       
  3422  * xmlSecXkmsRespondWithX509CRLGetKlass:
       
  3423  *
       
  3424  * The respond with X509CRL klass.
       
  3425  *
       
  3426  * Returns respond with X509CRL klass.
       
  3427  */
       
  3428 EXPORT_C 
       
  3429 xmlSecXkmsRespondWithId	
       
  3430 xmlSecXkmsRespondWithX509CRLGetKlass(void) {
       
  3431     return(&xmlSecXkmsRespondWithX509CRLKlass);
       
  3432 }
       
  3433 
       
  3434 static  int  
       
  3435 xmlSecXkmsRespondWithX509CRLNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
       
  3436 				      xmlNodePtr node) {
       
  3437     int ret;
       
  3438 
       
  3439     xmlSecAssert2(id == xmlSecXkmsRespondWithX509CRLId, -1);
       
  3440     xmlSecAssert2(ctx != NULL, -1);
       
  3441     xmlSecAssert2(node != NULL, -1);
       
  3442 
       
  3443     /* do usual stuff */
       
  3444     ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
       
  3445     if(ret < 0) {
       
  3446 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3447 		    xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
       
  3448 		    "xmlSecXkmsRespondWithDefaultNodeRead",
       
  3449 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3450 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  3451 	return(-1);  	
       
  3452     }
       
  3453     
       
  3454     return(0);
       
  3455 }
       
  3456 
       
  3457 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithPGPKlass = {
       
  3458     xmlSecRespondWithPGP,			/* const xmlChar* valueName; */
       
  3459     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3460     xmlSecNodePGPData,				/* const xmlChar* nodeName; */
       
  3461     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3462     xmlSecXkmsRespondWithDefaultNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3463     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3464     NULL,                                       /* void* reserved1; */
       
  3465     NULL                                        /* void* reserved2; */
       
  3466 };
       
  3467 
       
  3468 /**
       
  3469  * xmlSecXkmsRespondWithPGPGetKlass:
       
  3470  *
       
  3471  * The respond with PGP klass.
       
  3472  *
       
  3473  * Returns respond with PGP klass.
       
  3474  */
       
  3475 EXPORT_C 
       
  3476 xmlSecXkmsRespondWithId	
       
  3477 xmlSecXkmsRespondWithPGPGetKlass(void) {
       
  3478     return(&xmlSecXkmsRespondWithPGPKlass);
       
  3479 }
       
  3480 
       
  3481 static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithSPKIKlass = {
       
  3482     xmlSecRespondWithSPKI,			/* const xmlChar* valueName; */
       
  3483     xmlSecXkmsNs,			        /* const xmlChar* valueNs; */
       
  3484     xmlSecNodeSPKIData,				/* const xmlChar* nodeName; */
       
  3485     xmlSecDSigNs,				/* const xmlChar* nodeNs; */
       
  3486     xmlSecXkmsRespondWithDefaultNodeRead,	/* xmlSecXkmsRespondWithNodeReadMethod readNode; */
       
  3487     xmlSecXkmsRespondWithDefaultNodeWrite,	/* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
       
  3488     NULL,                                       /* void* reserved1; */
       
  3489     NULL                                        /* void* reserved2; */
       
  3490 };
       
  3491 
       
  3492 /**
       
  3493  * xmlSecXkmsRespondWithSPKIGetKlass:
       
  3494  *
       
  3495  * The respond with SPKI klass.
       
  3496  *
       
  3497  * Returns respond with SPKI klass.
       
  3498  */
       
  3499 EXPORT_C 
       
  3500 xmlSecXkmsRespondWithId	
       
  3501 xmlSecXkmsRespondWithSPKIGetKlass(void) {
       
  3502     return(&xmlSecXkmsRespondWithSPKIKlass);
       
  3503 }
       
  3504 
       
  3505 /**************************************************************************
       
  3506  *
       
  3507  * Global xmlSecXkmsServerRequestIds list functions
       
  3508  *
       
  3509  *************************************************************************/
       
  3510 static xmlSecPtrList xmlSecAllXkmsServerRequestIds;
       
  3511 
       
  3512 
       
  3513 /** 
       
  3514  * xmlSecXkmsServerRequestIdsGet:
       
  3515  *
       
  3516  * Gets global registered ServerRequest klasses list.
       
  3517  * 
       
  3518  * Returns the pointer to list of all registered ServerRequest klasses.
       
  3519  */
       
  3520 EXPORT_C
       
  3521 xmlSecPtrListPtr
       
  3522 xmlSecXkmsServerRequestIdsGet(void) {
       
  3523     return(&xmlSecAllXkmsServerRequestIds);
       
  3524 }
       
  3525 
       
  3526 /** 
       
  3527  * xmlSecXkmsServerRequestIdsInit:
       
  3528  *
       
  3529  * Initializes the ServerRequest klasses. This function is called from the 
       
  3530  * #xmlSecInit function and the application should not call it directly.
       
  3531  *
       
  3532  * Returns 0 on success or a negative value if an error occurs.
       
  3533  */
       
  3534 EXPORT_C
       
  3535 int 
       
  3536 xmlSecXkmsServerRequestIdsInit(void) {
       
  3537     int ret;
       
  3538     
       
  3539     ret = xmlSecPtrListInitialize(xmlSecXkmsServerRequestIdsGet(), xmlSecXkmsServerRequestIdListId);
       
  3540     if(ret < 0) {
       
  3541 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3542 		    NULL,
       
  3543 		    "xmlSecPtrListPtrInitialize",
       
  3544 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3545 		    "xmlSecXkmsServerRequestIdListId");
       
  3546         return(-1);
       
  3547     }
       
  3548     
       
  3549     ret = xmlSecXkmsServerRequestIdsRegisterDefault();
       
  3550     if(ret < 0) {
       
  3551 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3552 		    NULL,
       
  3553 		    "xmlSecXkmsServerRequestIdsRegisterDefault",
       
  3554 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3555 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  3556         return(-1);
       
  3557     }
       
  3558     
       
  3559     return(0);
       
  3560 }
       
  3561 
       
  3562 /**
       
  3563  *  xmlSecXkmsServerRequestIdsShutdown:
       
  3564  * 
       
  3565  * Shuts down the keys data klasses. This function is called from the 
       
  3566  * #xmlSecShutdown function and the application should not call it directly.
       
  3567  */
       
  3568 EXPORT_C
       
  3569 void
       
  3570 xmlSecXkmsServerRequestIdsShutdown(void) {
       
  3571     xmlSecPtrListFinalize(xmlSecXkmsServerRequestIdsGet());
       
  3572 }
       
  3573 
       
  3574 /** 
       
  3575  * xmlSecXkmsServerRequestIdsRegister:
       
  3576  * @id:		the ServerRequest klass.
       
  3577  *
       
  3578  * Registers @id in the global list of ServerRequest klasses.
       
  3579  *
       
  3580  * Returns 0 on success or a negative value if an error occurs.
       
  3581  */
       
  3582 EXPORT_C
       
  3583 int 
       
  3584 xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestId id) {
       
  3585     int ret;
       
  3586         
       
  3587     xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
       
  3588     
       
  3589     ret = xmlSecPtrListAdd(xmlSecXkmsServerRequestIdsGet(), (xmlSecPtr)id);
       
  3590     if(ret < 0) {
       
  3591 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3592 		    NULL,
       
  3593 		    "xmlSecPtrListAdd",
       
  3594 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3595 		    "ServerRequest=%s",
       
  3596 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(id)));
       
  3597         return(-1);
       
  3598     }
       
  3599     
       
  3600     return(0);    
       
  3601 }
       
  3602 
       
  3603 /**
       
  3604  * xmlSecXkmsServerRequestIdsRegisterDefault:
       
  3605  *
       
  3606  * Registers default (implemented by XML Security Library)
       
  3607  * ServerRequest klasses: KeyName, KeyValue,...
       
  3608  *
       
  3609  * Returns 0 on success or a negative value if an error occurs.
       
  3610  */
       
  3611 EXPORT_C
       
  3612 int 
       
  3613 xmlSecXkmsServerRequestIdsRegisterDefault(void) {
       
  3614     if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestResultId) < 0) {
       
  3615 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3616 		    NULL,
       
  3617 		    "xmlSecXkmsServerRequestIdsRegister",	    
       
  3618 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3619 		    "name=%s",
       
  3620 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestResultId)));
       
  3621 	return(-1);
       
  3622     }
       
  3623 
       
  3624     if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestStatusId) < 0) {
       
  3625 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3626 		    NULL,
       
  3627 		    "xmlSecXkmsServerRequestIdsRegister",	    
       
  3628 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3629 		    "name=%s",
       
  3630 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestStatusId)));
       
  3631 	return(-1);
       
  3632     }
       
  3633 
       
  3634     if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestCompoundId) < 0) {
       
  3635 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3636 		    NULL,
       
  3637 		    "xmlSecXkmsServerRequestIdsRegister",	    
       
  3638 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3639 		    "name=%s",
       
  3640 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestCompoundId)));
       
  3641 	return(-1);
       
  3642     }
       
  3643 
       
  3644     if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestLocateId) < 0) {
       
  3645 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3646 		    NULL,
       
  3647 		    "xmlSecXkmsServerRequestIdsRegister",	    
       
  3648 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3649 		    "name=%s",
       
  3650 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestLocateId)));
       
  3651 	return(-1);
       
  3652     }
       
  3653 
       
  3654     if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestValidateId) < 0) {
       
  3655 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3656 		    NULL,
       
  3657 		    "xmlSecXkmsServerRequestIdsRegister",	    
       
  3658 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3659 		    "name=%s",
       
  3660 		    xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestValidateId)));
       
  3661 	return(-1);
       
  3662     }
       
  3663 
       
  3664     return(0);
       
  3665 }
       
  3666 
       
  3667 
       
  3668 /************************************************************************
       
  3669  *
       
  3670  * XKMS ServerRequest Klass
       
  3671  *
       
  3672  ************************************************************************/ 
       
  3673 /**
       
  3674  * xmlSecXkmsServerRequestNodeRead:
       
  3675  * @id:		the ServerRequest class.
       
  3676  * @ctx:	the XKMS request processing context.
       
  3677  * @node:	the pointer to <xkms:ServerRequest/> node.
       
  3678  *
       
  3679  * Reads the content of the <xkms:ServerRequest/> @node.
       
  3680  *
       
  3681  * Returns 0 on success or a negative value if an error occurs.
       
  3682  */
       
  3683 EXPORT_C
       
  3684 int  
       
  3685 xmlSecXkmsServerRequestNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx,
       
  3686 			      xmlNodePtr node) {
       
  3687     xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
       
  3688     xmlSecAssert2(ctx != NULL, -1);
       
  3689     xmlSecAssert2(node != NULL, -1);
       
  3690 
       
  3691     if(id->readNode != NULL) {
       
  3692 	return((id->readNode)(id, ctx, node));
       
  3693     }
       
  3694     return(0);
       
  3695 }
       
  3696 
       
  3697 /**
       
  3698  * xmlSecXkmsServerExecute:
       
  3699  * @id:		the ServerRequest class.
       
  3700  * @ctx:	the XKMS request processing context.
       
  3701  *
       
  3702  * Executes XKMS server request.
       
  3703  *
       
  3704  * Returns 0 on success or a negative value if an error occurs.
       
  3705  */
       
  3706 EXPORT_C
       
  3707 int  
       
  3708 xmlSecXkmsServerRequestExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
       
  3709     xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
       
  3710     xmlSecAssert2(ctx != NULL, -1);
       
  3711 
       
  3712     if(id->execute != NULL) {
       
  3713 	return((id->execute)(id, ctx));
       
  3714     }
       
  3715     return(0);
       
  3716 }
       
  3717 
       
  3718 
       
  3719 /**
       
  3720  * xmlSecXkmsServerResponseNodeWrite:
       
  3721  * @id:		the ServerRequest class.
       
  3722  * @ctx:	the XKMS request processing context.
       
  3723  * @doc:	the pointer to response parent XML document (might be NULL).
       
  3724  * @node:       the pointer to response parent XML node (might be NULL).
       
  3725  *
       
  3726  * Writes XKMS response from context to a newly created node. Caller is 
       
  3727  * responsible for adding the returned node to the XML document.
       
  3728  *
       
  3729  * Returns pointer to newly created XKMS response node or NULL
       
  3730  * if an error occurs.
       
  3731  */
       
  3732 EXPORT_C
       
  3733 xmlNodePtr 
       
  3734 xmlSecXkmsServerRequestNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx,
       
  3735 			         xmlDocPtr doc, xmlNodePtr node) {
       
  3736     xmlNodePtr respNode;
       
  3737     int ret;
       
  3738     
       
  3739     xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, NULL);
       
  3740     xmlSecAssert2(ctx != NULL, NULL);
       
  3741 
       
  3742     /* create the response root node */
       
  3743     if(node == NULL) {
       
  3744         xmlNsPtr ns;
       
  3745         
       
  3746         respNode = xmlNewDocNode(doc, NULL, id->resultNodeName, NULL);
       
  3747         if(respNode == NULL) {
       
  3748 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  3749 		        NULL,
       
  3750 		        "xmlNewDocNode",
       
  3751 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  3752 		        "node=%s",
       
  3753 		        xmlSecErrorsSafeString(id->resultNodeName));
       
  3754             return(NULL);
       
  3755         }
       
  3756         ns = xmlNewNs(respNode, id->resultNodeNs, NULL);
       
  3757         if(ns == NULL) {
       
  3758 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  3759 		        NULL,
       
  3760 		        "xmlNewNs",
       
  3761 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  3762 		        "ns=%s",
       
  3763 		        xmlSecErrorsSafeString(id->resultNodeNs));
       
  3764             xmlFreeNode(respNode);
       
  3765             return(NULL);
       
  3766         }
       
  3767         xmlSetNs(respNode, ns);
       
  3768     } else {
       
  3769         respNode = xmlSecAddChild(node, id->resultNodeName, id->resultNodeNs);
       
  3770         if(respNode == NULL) {
       
  3771 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  3772 		        NULL,
       
  3773 		        "xmlSecAddChild",
       
  3774 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3775 		        "node=%s",
       
  3776 		        xmlSecErrorsSafeString(id->resultNodeName));
       
  3777             return(NULL);
       
  3778         }
       
  3779     }
       
  3780     
       
  3781     if(id->writeNode != NULL) {
       
  3782 	ret = (id->writeNode)(id, ctx, respNode);
       
  3783 	if(ret < 0) {
       
  3784             xmlSecError(XMLSEC_ERRORS_HERE,
       
  3785 		        NULL,
       
  3786 		        "writeNode",
       
  3787 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3788 		        "node=%s",
       
  3789 		        xmlSecErrorsSafeString(id->resultNodeName));
       
  3790             xmlFreeNode(respNode);
       
  3791             return(NULL);
       
  3792         }
       
  3793     }
       
  3794     
       
  3795     return(respNode);
       
  3796 }
       
  3797 
       
  3798 /**
       
  3799  * xmlSecXkmsServerRequestDebugDump:
       
  3800  * @id:			the ServerRequest class.
       
  3801  * @output:		the output file.
       
  3802  *
       
  3803  * Writes debug information about @id into the @output.
       
  3804  */
       
  3805 EXPORT_C
       
  3806 void 
       
  3807 xmlSecXkmsServerRequestDebugDump(xmlSecXkmsServerRequestId id, FILE* output) {
       
  3808     xmlSecAssert(id != xmlSecXkmsServerRequestIdUnknown);
       
  3809     xmlSecAssert(output != NULL);
       
  3810 
       
  3811     fprintf(output, "=== ServerRequest: %s\n", xmlSecErrorsSafeString(id->name));
       
  3812 }
       
  3813 
       
  3814 /**
       
  3815  * xmlSecXkmsServerRequestDebugXmlDump:
       
  3816  * @id:			the ServerRequest class.
       
  3817  * @output:		the output file.
       
  3818  *
       
  3819  * Writes debug information about @id into the @output in XML format.
       
  3820  */
       
  3821 EXPORT_C
       
  3822 void 
       
  3823 xmlSecXkmsServerRequestDebugXmlDump(xmlSecXkmsServerRequestId id, FILE* output) {
       
  3824     xmlSecAssert(id != xmlSecXkmsServerRequestIdUnknown);
       
  3825     xmlSecAssert(output != NULL);
       
  3826 
       
  3827     fprintf(output, "<ServerRequest>%s</ServerRequest>\n", xmlSecErrorsSafeString(id->name));
       
  3828 }
       
  3829 
       
  3830 /************************************************************************
       
  3831  *
       
  3832  * XKMS ServerRequest Klass List
       
  3833  *
       
  3834  ************************************************************************/ 
       
  3835 static xmlSecPtrListKlass xmlSecXkmsServerRequestIdListKlass = {
       
  3836     BAD_CAST "xkms-server-request-ids-list",
       
  3837     NULL, 								/* xmlSecPtrDuplicateItemMethod duplicateItem; */
       
  3838     NULL,								/* xmlSecPtrDestroyItemMethod destroyItem; */
       
  3839     (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerRequestDebugDump,	/* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
       
  3840     (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerRequestDebugXmlDump,	/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
       
  3841 };
       
  3842 EXPORT_C
       
  3843 
       
  3844 xmlSecPtrListId	
       
  3845 xmlSecXkmsServerRequestIdListGetKlass(void) {
       
  3846     return(&xmlSecXkmsServerRequestIdListKlass);
       
  3847 }
       
  3848 EXPORT_C
       
  3849 
       
  3850 int 
       
  3851 xmlSecXkmsServerRequestIdListFind(xmlSecPtrListPtr list, xmlSecXkmsServerRequestId id) {
       
  3852     xmlSecSize i, size;
       
  3853     
       
  3854     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsServerRequestIdListId), -1);
       
  3855     xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
       
  3856     
       
  3857     size = xmlSecPtrListGetSize(list);
       
  3858     for(i = 0; i < size; ++i) {
       
  3859 	if((xmlSecXkmsServerRequestId)xmlSecPtrListGetItem(list, i) == id) {
       
  3860 	    return(1);
       
  3861 	}
       
  3862     }
       
  3863     return(0);
       
  3864 }
       
  3865 EXPORT_C
       
  3866 
       
  3867 xmlSecXkmsServerRequestId 
       
  3868 xmlSecXkmsServerRequestIdListFindByName(xmlSecPtrListPtr list, const xmlChar* name) {
       
  3869     xmlSecXkmsServerRequestId id;
       
  3870     xmlSecSize i, size;
       
  3871     
       
  3872     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsServerRequestIdListId), xmlSecXkmsServerRequestIdUnknown);
       
  3873     xmlSecAssert2(name != NULL, xmlSecXkmsServerRequestIdUnknown);
       
  3874 
       
  3875     size = xmlSecPtrListGetSize(list);
       
  3876     for(i = 0; i < size; ++i) {
       
  3877 	id = (xmlSecXkmsServerRequestId)xmlSecPtrListGetItem(list, i);
       
  3878 	if((id !=  xmlSecXkmsServerRequestIdUnknown) && xmlStrEqual(id->name, name)) {
       
  3879 	    return(id);
       
  3880 	}
       
  3881     }
       
  3882     return(xmlSecXkmsServerRequestIdUnknown);    
       
  3883 }
       
  3884 EXPORT_C
       
  3885 
       
  3886 xmlSecXkmsServerRequestId 
       
  3887 xmlSecXkmsServerRequestIdListFindByNode(xmlSecPtrListPtr list, xmlNodePtr node) {
       
  3888     xmlSecXkmsServerRequestId id;
       
  3889     xmlSecSize i, size;
       
  3890     
       
  3891     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsServerRequestIdListId), xmlSecXkmsServerRequestIdUnknown);
       
  3892     xmlSecAssert2(node != NULL, xmlSecXkmsServerRequestIdUnknown);
       
  3893 
       
  3894     size = xmlSecPtrListGetSize(list);
       
  3895     for(i = 0; i < size; ++i) {
       
  3896 	id = (xmlSecXkmsServerRequestId)xmlSecPtrListGetItem(list, i);
       
  3897 	if((id !=  xmlSecXkmsServerRequestIdUnknown) &&
       
  3898             xmlSecCheckNodeName(node, id->requestNodeName, id->requestNodeNs)) {
       
  3899 
       
  3900 	    return(id);
       
  3901 	}
       
  3902     }
       
  3903     return(xmlSecXkmsServerRequestIdUnknown);    
       
  3904 }
       
  3905 
       
  3906 /******************************************************************** 
       
  3907  *
       
  3908  * XML Sec Library ServerRequest Ids
       
  3909  *
       
  3910  *******************************************************************/
       
  3911 
       
  3912 
       
  3913 /******************************************************************** 
       
  3914  *
       
  3915  * Result response
       
  3916  *
       
  3917  *******************************************************************/
       
  3918 static int		xmlSecXkmsServerRequestResultNodeWrite	(xmlSecXkmsServerRequestId id,
       
  3919 								 xmlSecXkmsServerCtxPtr ctx,
       
  3920 								 xmlNodePtr node);
       
  3921 
       
  3922 static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestResultKlass = {
       
  3923     xmlSecXkmsServerRequestResultName,		/* const xmlChar* name; */
       
  3924     NULL,					/* const xmlChar* requestNodeName; */
       
  3925     NULL,					/* const xmlChar* requestNodeNs; */
       
  3926     xmlSecNodeResult,				/* const xmlChar* responseNodeName; */
       
  3927     xmlSecXkmsNs,				/* const xmlChar* responseNodeNs; */
       
  3928     0,                                          /* xmlSecBitMask flags; */
       
  3929     NULL,					/* xmlSecXkmsServerRequestNodeReadMethod readNode; */
       
  3930     xmlSecXkmsServerRequestResultNodeWrite,	/* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
       
  3931     NULL,					/* xmlSecXkmsServerRequestExecuteMethod execute; */
       
  3932     NULL,                                       /* void* reserved1; */
       
  3933     NULL                                        /* void* reserved2; */
       
  3934 };
       
  3935 
       
  3936 /**
       
  3937  * xmlSecXkmsServerRequestResultGetKlass:
       
  3938  *
       
  3939  * The Result response klass.
       
  3940  *
       
  3941  * Returns Result response klass.
       
  3942  */
       
  3943 EXPORT_C 
       
  3944 xmlSecXkmsServerRequestId	
       
  3945 xmlSecXkmsServerRequestResultGetKlass(void) {
       
  3946     return(&xmlSecXkmsServerRequestResultKlass);
       
  3947 }
       
  3948 
       
  3949 static int 
       
  3950 xmlSecXkmsServerRequestResultNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  3951     int ret;
       
  3952     
       
  3953     xmlSecAssert2(id == xmlSecXkmsServerRequestResultId, -1);
       
  3954     xmlSecAssert2(ctx != NULL, -1);
       
  3955     xmlSecAssert2(node != NULL, -1);
       
  3956 
       
  3957     /* set missing parameters (if any) */
       
  3958     if(ctx->service == NULL) {
       
  3959 	ctx->service = xmlStrdup((ctx->expectedService != NULL) ? ctx->expectedService : BAD_CAST "");
       
  3960 	if(ctx->service == NULL) {
       
  3961 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  3962 			NULL,
       
  3963 			"xmlStrdup",
       
  3964 		        XMLSEC_ERRORS_R_MALLOC_FAILED,
       
  3965 			XMLSEC_ERRORS_NO_MESSAGE);
       
  3966 	    return(-1);
       
  3967 	}
       
  3968     }
       
  3969     
       
  3970     /* first write the "parent" type */
       
  3971     ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
       
  3972     if(ret < 0) {
       
  3973 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  3974 		    NULL,
       
  3975 		    "xmlSecXkmsServerCtxResultTypeNodeWrite",
       
  3976 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  3977 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  3978 	return(-1);  	
       
  3979     }
       
  3980 
       
  3981     return(0);
       
  3982 }
       
  3983 
       
  3984 /******************************************************************** 
       
  3985  *
       
  3986  * StatusRequest/StatusResponse
       
  3987  *
       
  3988  *******************************************************************/
       
  3989 static int  		xmlSecXkmsServerRequestStatusNodeRead	(xmlSecXkmsServerRequestId id,
       
  3990 								 xmlSecXkmsServerCtxPtr ctx,
       
  3991 								 xmlNodePtr node);
       
  3992 static int		xmlSecXkmsServerRequestStatusNodeWrite	(xmlSecXkmsServerRequestId id,
       
  3993 								 xmlSecXkmsServerCtxPtr ctx,
       
  3994 								 xmlNodePtr node);
       
  3995 
       
  3996 static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestStatusKlass = {
       
  3997     xmlSecXkmsServerRequestStatusName,		/* const xmlChar* name; */
       
  3998     xmlSecNodeStatusRequest,			/* const xmlChar* requestNodeName; */
       
  3999     xmlSecXkmsNs,				/* const xmlChar* requestNodeNs; */
       
  4000     xmlSecNodeStatusResult,			/* const xmlChar* responseNodeName; */
       
  4001     xmlSecXkmsNs,				/* const xmlChar* responseNodeNs; */
       
  4002     0,                                          /* xmlSecBitMask flags; */
       
  4003     xmlSecXkmsServerRequestStatusNodeRead,	/* xmlSecXkmsServerRequestNodeReadMethod readNode; */
       
  4004     xmlSecXkmsServerRequestStatusNodeWrite,	/* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
       
  4005     NULL,					/* xmlSecXkmsServerRequestExecuteMethod execute; */
       
  4006     NULL,                                       /* void* reserved1; */
       
  4007     NULL                                        /* void* reserved2; */
       
  4008 };
       
  4009 
       
  4010 /**
       
  4011  * xmlSecXkmsServerRequestStatusGetKlass:
       
  4012  *
       
  4013  * The StatusRequest klass.
       
  4014  *
       
  4015  * Returns StatusRequest klass.
       
  4016  */
       
  4017 EXPORT_C 
       
  4018 xmlSecXkmsServerRequestId	
       
  4019 xmlSecXkmsServerRequestStatusGetKlass(void) {
       
  4020     return(&xmlSecXkmsServerRequestStatusKlass);
       
  4021 }
       
  4022 
       
  4023 /**
       
  4024  * 
       
  4025  *  <xkms:StatusRequest Id Service Nonce? OriginalRequestId? ResponseLimit? ResponseId?>
       
  4026  *      <ds:Signature>?
       
  4027  *      <xkms:MessageExtension>*
       
  4028  *      (<xkms:OpaqueClientData>
       
  4029  *          <xkms:OpaqueData>?
       
  4030  *      )?
       
  4031  *      <xkms:ResponseMechanism>*
       
  4032  *      <xkms:RespondWith>*
       
  4033  *      <xkms:PendingNotification Mechanism Identifier>?
       
  4034  *  
       
  4035  * XML Schema:
       
  4036  *    <!-- StatusRequest -->   
       
  4037  *    <element name="StatusRequest" type="xkms:StatusRequestType"/>   
       
  4038  *    <complexType name="StatusRequestType">      
       
  4039  *        <complexContent>         
       
  4040  *            <extension base="xkms:PendingRequestType"/>      
       
  4041  *        </complexContent>   
       
  4042  *    </complexType>   
       
  4043  *    <!-- /StatusRequest -->
       
  4044  */
       
  4045 static int  
       
  4046 xmlSecXkmsServerRequestStatusNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4047     xmlNodePtr cur;
       
  4048     int ret;
       
  4049     
       
  4050     xmlSecAssert2(id == xmlSecXkmsServerRequestStatusId, -1);
       
  4051     xmlSecAssert2(ctx != NULL, -1);
       
  4052     xmlSecAssert2(node != NULL, -1);
       
  4053 
       
  4054     cur = node;
       
  4055     
       
  4056     /* first read "parent" type */
       
  4057     ret = xmlSecXkmsServerCtxPendingRequestNodeRead(ctx, &cur);
       
  4058     if(ret < 0) {
       
  4059     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4060 		    NULL,
       
  4061 		    "xmlSecXkmsServerCtxPendingRequestNodeRead",
       
  4062 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4063 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4064 	return(-1);
       
  4065     }
       
  4066 
       
  4067     /* check that there is nothing after the last node */
       
  4068     if(cur != NULL) {
       
  4069 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4070 		    NULL,
       
  4071 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  4072 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
  4073 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4074 	return(-1);
       
  4075     }
       
  4076 
       
  4077     return(0);
       
  4078 }
       
  4079 
       
  4080 /**
       
  4081  * 
       
  4082  *  <xkms:StatusResult Id Service Nonce? ResultMajor ResultMinor? RequestId? Success? Failure? Pending?>
       
  4083  *      <ds:Signature>?
       
  4084  *      <xkms:MessageExtension>*
       
  4085  *      (<xkms:OpaqueClientData>
       
  4086  *          <xkms:OpaqueData>?
       
  4087  *      )?
       
  4088  *      <xkms:RequestSignatureValue>*
       
  4089  *
       
  4090  * XML Schema:
       
  4091  * 
       
  4092  *    <!-- StatusResult -->   
       
  4093  *    <element name="StatusResult" type="xkms:StatusResultType"/>   
       
  4094  *    <complexType name="StatusResultType">      
       
  4095  *        <complexContent>
       
  4096  *            <extension base="xkms:ResultType">
       
  4097  *                <attribute name="Success" type="integer" use="optional"/>
       
  4098  *                <attribute name="Failure" type="integer" use="optional"/>
       
  4099  *                <attribute name="Pending" type="integer" use="optional"/>
       
  4100  *            </extension>
       
  4101  *        </complexContent>
       
  4102  *    </complexType>
       
  4103  *    <!-- /StatusResult --> *
       
  4104  */ 
       
  4105 static int 
       
  4106 xmlSecXkmsServerRequestStatusNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4107     int ret;
       
  4108 
       
  4109     xmlSecAssert2(id == xmlSecXkmsServerRequestStatusId, -1);
       
  4110     xmlSecAssert2(ctx != NULL, -1);
       
  4111     xmlSecAssert2(node != NULL, -1);
       
  4112 
       
  4113     /* first write the "parent" type */
       
  4114     ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
       
  4115     if(ret < 0) {
       
  4116 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4117 		    NULL,
       
  4118 		    "xmlSecXkmsServerCtxResultTypeNodeWrite",
       
  4119 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4120 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4121 	return(-1);  	
       
  4122     }
       
  4123     
       
  4124     return(0);
       
  4125 }
       
  4126 
       
  4127 /******************************************************************** 
       
  4128  *
       
  4129  * CompoundRequest/CompoundResponse
       
  4130  *
       
  4131  *******************************************************************/
       
  4132 static int  		xmlSecXkmsServerRequestCompoundNodeRead	(xmlSecXkmsServerRequestId id,
       
  4133 								 xmlSecXkmsServerCtxPtr ctx,
       
  4134 								 xmlNodePtr node);
       
  4135 static int		xmlSecXkmsServerRequestCompoundNodeWrite(xmlSecXkmsServerRequestId id,
       
  4136 								 xmlSecXkmsServerCtxPtr ctx,
       
  4137 								 xmlNodePtr node);
       
  4138 static int 		xmlSecXkmsServerRequestCompoundExecute	(xmlSecXkmsServerRequestId id, 
       
  4139 								 xmlSecXkmsServerCtxPtr ctx);
       
  4140 
       
  4141 static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestCompoundKlass = {
       
  4142     xmlSecXkmsServerRequestCompoundName,	/* const xmlChar* name; */
       
  4143     xmlSecNodeCompoundRequest,			/* const xmlChar* requestNodeName; */
       
  4144     xmlSecXkmsNs,				/* const xmlChar* requestNodeNs; */
       
  4145     xmlSecNodeCompoundResult,			/* const xmlChar* responseNodeName; */
       
  4146     xmlSecXkmsNs,				/* const xmlChar* responseNodeNs; */
       
  4147     0,                                          /* xmlSecBitMask flags; */
       
  4148     xmlSecXkmsServerRequestCompoundNodeRead,	/* xmlSecXkmsServerRequestNodeReadMethod readNode; */
       
  4149     xmlSecXkmsServerRequestCompoundNodeWrite,	/* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
       
  4150     xmlSecXkmsServerRequestCompoundExecute,	/* xmlSecXkmsServerRequestExecuteMethod execute; */
       
  4151     NULL,                                       /* void* reserved1; */
       
  4152     NULL                                        /* void* reserved2; */
       
  4153 };
       
  4154 
       
  4155 /**
       
  4156  * xmlSecXkmsServerRequestCompoundGetKlass:
       
  4157  *
       
  4158  * The CompoundRequest klass.
       
  4159  *
       
  4160  * Returns CompoundRequest klass.
       
  4161  */
       
  4162 EXPORT_C 
       
  4163 xmlSecXkmsServerRequestId	
       
  4164 xmlSecXkmsServerRequestCompoundGetKlass(void) {
       
  4165     return(&xmlSecXkmsServerRequestCompoundKlass);
       
  4166 }
       
  4167 
       
  4168 /**
       
  4169  *  <xkms:CompoundRequest Id Service Nonce? OriginalRequestId? ResponseLimit?>
       
  4170  *      <ds:Signature>?
       
  4171  *      <xkms:MessageExtension>*
       
  4172  *      (<xkms:OpaqueClientData>
       
  4173  *          <xkms:OpaqueData>?
       
  4174  *      )?
       
  4175  *      <xkms:ResponseMechanism>*
       
  4176  *      <xkms:RespondWith>*
       
  4177  *      <xkms:PendingNotification Mechanism Identifier>?
       
  4178  *      (
       
  4179  *       <xkms:LocateRequest>?
       
  4180  *       <xkms:ValidateRequest>?
       
  4181  *       <xkms:RegisterRequest>?
       
  4182  *       <xkms:ReissueRequest>?
       
  4183  *       <xkms:RecoverRequest>?
       
  4184  *       <xkms:RevokeRequest>?
       
  4185  *      )*
       
  4186  *       
       
  4187  * XML Schema:
       
  4188  *
       
  4189  *    <!-- CompoundRequest -->   
       
  4190  *    <element name="CompoundRequest" type="xkms:CompoundRequestType"/>   
       
  4191  *    <complexType name="CompoundRequestType">      
       
  4192  *        <complexContent>         
       
  4193  *            <extension base="xkms:RequestAbstractType">            
       
  4194  *                <choice maxOccurs="unbounded">               
       
  4195  *                    <element ref="xkms:LocateRequest"/>               
       
  4196  *                    <element ref="xkms:ValidateRequest"/>               
       
  4197  *                    <element ref="xkms:RegisterRequest"/>               
       
  4198  *                    <element ref="xkms:ReissueRequest"/>               
       
  4199  *                    <element ref="xkms:RecoverRequest"/>               
       
  4200  *                    <element ref="xkms:RevokeRequest"/>            
       
  4201  *                </choice>         
       
  4202  *            </extension>      
       
  4203  *        </complexContent>   
       
  4204  *    </complexType>   
       
  4205  *    <!-- /CompoundRequest -->
       
  4206  */
       
  4207 static int  
       
  4208 xmlSecXkmsServerRequestCompoundNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4209     xmlSecPtrListPtr serverRequestIdsList;
       
  4210     xmlNodePtr cur;
       
  4211     int ret;
       
  4212     
       
  4213     xmlSecAssert2(id == xmlSecXkmsServerRequestCompoundId, -1);
       
  4214     xmlSecAssert2(ctx != NULL, -1);
       
  4215     xmlSecAssert2(node != NULL, -1);
       
  4216 
       
  4217     cur = node;
       
  4218     
       
  4219     /* first read "parent" type */
       
  4220     ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, &cur);
       
  4221     if(ret < 0) {
       
  4222     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4223 		    NULL,
       
  4224 		    "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
       
  4225 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4226 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4227 	return(-1);
       
  4228     }
       
  4229 
       
  4230     /* create list for compound requests */
       
  4231     xmlSecAssert2(ctx->compoundRequestContexts == NULL, -1);
       
  4232     ctx->compoundRequestContexts = xmlSecPtrListCreate(xmlSecXkmsServerCtxPtrListId);
       
  4233     if(ctx->compoundRequestContexts == NULL) {
       
  4234     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4235 		    NULL,
       
  4236 		    "xmlSecPtrListCreate",
       
  4237 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4238 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4239 	return(-1);
       
  4240     }
       
  4241 
       
  4242     /* get the list of enabled or all request klasses */
       
  4243     if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
       
  4244 	serverRequestIdsList = &(ctx->enabledServerRequestIds);
       
  4245     } else {
       
  4246 	serverRequestIdsList = xmlSecXkmsServerRequestIdsGet();
       
  4247     }
       
  4248     xmlSecAssert2(serverRequestIdsList != NULL, -1); 
       
  4249     
       
  4250     while(cur != NULL) {
       
  4251         xmlSecXkmsServerCtxPtr ctxChild;    
       
  4252         
       
  4253         /* create a new context */
       
  4254         ctxChild = xmlSecXkmsServerCtxCreate(ctx->keyInfoReadCtx.keysMngr);
       
  4255         if(ctxChild == NULL) {
       
  4256             xmlSecError(XMLSEC_ERRORS_HERE,
       
  4257 		        NULL,
       
  4258 		        "xmlSecXkmsServerCtxCreate",
       
  4259 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4260 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  4261 	    return(-1);
       
  4262         }
       
  4263 
       
  4264         /* copy all settings from us */
       
  4265         ret = xmlSecXkmsServerCtxCopyUserPref(ctxChild, ctx);
       
  4266         if(ret < 0) {
       
  4267             xmlSecError(XMLSEC_ERRORS_HERE,
       
  4268 		        NULL,
       
  4269 		        "xmlSecXkmsServerCtxCopyUserPref",
       
  4270 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4271 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  4272             xmlSecXkmsServerCtxDestroy(ctxChild);
       
  4273 	    return(-1);
       
  4274         }
       
  4275 
       
  4276         /* add it to the list */
       
  4277         ret = xmlSecPtrListAdd(ctx->compoundRequestContexts, ctxChild);
       
  4278         if(ret < 0) {
       
  4279             xmlSecError(XMLSEC_ERRORS_HERE,
       
  4280 		        NULL,
       
  4281 		        "xmlSecPtrListAdd",
       
  4282 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4283 		        XMLSEC_ERRORS_NO_MESSAGE);
       
  4284             xmlSecXkmsServerCtxDestroy(ctxChild);
       
  4285 	    return(-1);
       
  4286         }
       
  4287 
       
  4288         /* and now process request from current node */
       
  4289         ctxChild->requestId = xmlSecXkmsServerRequestIdListFindByNode(serverRequestIdsList, cur);
       
  4290         if((ctxChild->requestId == xmlSecXkmsServerRequestIdUnknown) || 
       
  4291            ((ctxChild->requestId->flags & XMLSEC_XKMS_SERVER_REQUEST_KLASS_ALLOWED_IN_COUMPOUND) == 0)) {
       
  4292             xmlSecError(XMLSEC_ERRORS_HERE,
       
  4293 		        NULL,
       
  4294 		        "xmlSecXkmsServerRequestIdListFindByNode",
       
  4295 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4296 		        "node=%s",
       
  4297 		        xmlSecErrorsSafeString(node->name));
       
  4298 	    xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorMessageNotSupported);
       
  4299 	    return(-1);
       
  4300         }
       
  4301 
       
  4302         ret = xmlSecXkmsServerRequestNodeRead(ctxChild->requestId, ctxChild, cur);
       
  4303         if(ret < 0) {
       
  4304     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  4305 		        NULL,
       
  4306 		        "xmlSecXkmsServerRequestNodeRead",
       
  4307 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4308 		        "request=%s",
       
  4309 		        xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctxChild->requestId)));
       
  4310 	    xmlSecXkmsServerCtxSetResult(ctxChild, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
  4311 	    return(-1);
       
  4312         }
       
  4313         cur = xmlSecGetNextElementNode(cur->next);
       
  4314     }
       
  4315 
       
  4316     /* check that there is nothing after the last node */
       
  4317     if(cur != NULL) {
       
  4318 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4319 		    NULL,
       
  4320 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  4321 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
  4322 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4323 	return(-1);
       
  4324     }
       
  4325 
       
  4326     return(0);
       
  4327 }
       
  4328 
       
  4329 /**
       
  4330  *  <xkms:CompoundResult Id Service Nonce? ResultMajor ResultMinor? RequestId?>
       
  4331  *      <ds:Signature>?
       
  4332  *      <xkms:MessageExtension>*
       
  4333  *      (<xkms:OpaqueClientData>
       
  4334  *          <xkms:OpaqueData>?
       
  4335  *      )?
       
  4336  *      <xkms:RequestSignatureValue>*
       
  4337  *      (
       
  4338  *       <xkms:LocateResult>?
       
  4339  *       <xkms:ValidateResult>?
       
  4340  *       <xkms:RegisterResult>?
       
  4341  *       <xkms:ReissueResult>?
       
  4342  *       <xkms:RecoverResult>?
       
  4343  *       <xkms:RevokeResult>?
       
  4344  *      )*
       
  4345  *
       
  4346  * 
       
  4347  * XML Schema:
       
  4348  *
       
  4349  *    <!-- CompoundResponse -->   
       
  4350  *    <element name="CompoundResult" type="xkms:CompoundResultType"/>   
       
  4351  *    <complexType name="CompoundResultType">      
       
  4352  *        <complexContent>         
       
  4353  *            <extension base="xkms:ResultType">            
       
  4354  *                <choice maxOccurs="unbounded">               
       
  4355  *                    <element ref="xkms:LocateResult"/>
       
  4356  *                    <element ref="xkms:ValidateResult"/>
       
  4357  *                    <element ref="xkms:RegisterResult"/>
       
  4358  *                    <element ref="xkms:ReissueResult"/>
       
  4359  *                    <element ref="xkms:RecoverResult"/>
       
  4360  *                    <element ref="xkms:RevokeResult"/>
       
  4361  *                </choice>
       
  4362  *            </extension>
       
  4363  *        </complexContent>
       
  4364  *   </complexType>
       
  4365  *   <!-- /CompoundResponse -->
       
  4366  */ 
       
  4367 static int 
       
  4368 xmlSecXkmsServerRequestCompoundNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4369     int ret;
       
  4370 
       
  4371     xmlSecAssert2(id == xmlSecXkmsServerRequestCompoundId, -1);
       
  4372     xmlSecAssert2(ctx != NULL, -1);
       
  4373     xmlSecAssert2(node != NULL, -1);
       
  4374 
       
  4375     /* walk thru the list of chilren and pickup first error */
       
  4376     if(ctx->compoundRequestContexts != NULL) {
       
  4377         xmlSecSize pos;
       
  4378 
       
  4379         for(pos = 0; pos < xmlSecPtrListGetSize(ctx->compoundRequestContexts); pos++) {
       
  4380             xmlSecXkmsServerCtxPtr ctxChild;
       
  4381 
       
  4382             ctxChild = (xmlSecXkmsServerCtxPtr)xmlSecPtrListGetItem(ctx->compoundRequestContexts, pos);
       
  4383             if(ctxChild == NULL) {
       
  4384 	        xmlSecError(XMLSEC_ERRORS_HERE,
       
  4385 		            NULL,
       
  4386 		            "xmlSecPtrListGetItem",
       
  4387 		            XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4388 		            XMLSEC_ERRORS_NO_MESSAGE);
       
  4389 	        return(-1);  	
       
  4390             }
       
  4391 	    
       
  4392 	    if(ctxChild->resultMajor != xmlSecXkmsResultMajorSuccess) {
       
  4393 	        xmlSecXkmsServerCtxSetResult(ctx, ctxChild->resultMajor, ctxChild->resultMinor);
       
  4394 		break;
       
  4395 	    }
       
  4396 	}
       
  4397     }
       
  4398     
       
  4399     /* first write the "parent" type */
       
  4400     ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
       
  4401     if(ret < 0) {
       
  4402 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4403 		    NULL,
       
  4404 		    "xmlSecXkmsServerCtxResultTypeNodeWrite",
       
  4405 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4406 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4407 	return(-1);  	
       
  4408     }
       
  4409     
       
  4410     /* write compound result */
       
  4411     if(ctx->compoundRequestContexts != NULL) {
       
  4412         xmlSecSize pos;
       
  4413 
       
  4414         for(pos = 0; pos < xmlSecPtrListGetSize(ctx->compoundRequestContexts); pos++) {
       
  4415             xmlSecXkmsServerCtxPtr ctxChild;
       
  4416             xmlNodePtr cur;
       
  4417 
       
  4418             ctxChild = (xmlSecXkmsServerCtxPtr)xmlSecPtrListGetItem(ctx->compoundRequestContexts, pos);
       
  4419             if(ctxChild == NULL) {
       
  4420 	        xmlSecError(XMLSEC_ERRORS_HERE,
       
  4421 		            NULL,
       
  4422 		            "xmlSecPtrListGetItem",
       
  4423 		            XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4424 		            XMLSEC_ERRORS_NO_MESSAGE);
       
  4425 	        return(-1);  	
       
  4426             }
       
  4427             
       
  4428             cur = xmlSecXkmsServerRequestNodeWrite(ctxChild->requestId, ctxChild, node->doc, node);
       
  4429             if(cur == NULL) {
       
  4430     	        xmlSecError(XMLSEC_ERRORS_HERE,
       
  4431 		            NULL,
       
  4432 		            "xmlSecXkmsServerRequestNodeWrite",
       
  4433 		            XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4434 		            "request=%s",
       
  4435 		            xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctxChild->requestId)));
       
  4436                 return(-1);
       
  4437             }
       
  4438             
       
  4439             if(xmlSecAddChildNode(node, cur) == NULL) {
       
  4440 	        xmlSecError(XMLSEC_ERRORS_HERE,
       
  4441 			    NULL,
       
  4442 			    "xmlSecAddChildNode",
       
  4443 			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4444 			    XMLSEC_ERRORS_NO_MESSAGE);
       
  4445                 xmlFreeNode(cur);
       
  4446                 return(-1);
       
  4447 	    }
       
  4448         }
       
  4449     }
       
  4450 
       
  4451     return(0);
       
  4452 }
       
  4453 
       
  4454 static int 
       
  4455 xmlSecXkmsServerRequestCompoundExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
       
  4456     int ret;
       
  4457     
       
  4458     xmlSecAssert2(id == xmlSecXkmsServerRequestCompoundId, -1);
       
  4459     xmlSecAssert2(ctx != NULL, -1);
       
  4460 
       
  4461     if(ctx->compoundRequestContexts != NULL) {
       
  4462         xmlSecSize pos;
       
  4463 
       
  4464         for(pos = 0; pos < xmlSecPtrListGetSize(ctx->compoundRequestContexts); pos++) {
       
  4465             xmlSecXkmsServerCtxPtr ctxChild;
       
  4466 
       
  4467             ctxChild = (xmlSecXkmsServerCtxPtr)xmlSecPtrListGetItem(ctx->compoundRequestContexts, pos);
       
  4468             if(ctxChild == NULL) {
       
  4469 	        xmlSecError(XMLSEC_ERRORS_HERE,
       
  4470 		            NULL,
       
  4471 		            "xmlSecPtrListGetItem",
       
  4472 		            XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4473 		            XMLSEC_ERRORS_NO_MESSAGE);
       
  4474 	        xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
       
  4475 	        continue;  	
       
  4476             }
       
  4477             
       
  4478             ret = xmlSecXkmsServerRequestExecute(ctxChild->requestId, ctxChild);
       
  4479             if(ret < 0) {
       
  4480     	        xmlSecError(XMLSEC_ERRORS_HERE,
       
  4481 		            NULL,
       
  4482 		            "xmlSecXkmsServerRequestExecute",
       
  4483 		            XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4484 		            "request=%s",
       
  4485 		            xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctxChild->requestId)));
       
  4486 	        xmlSecXkmsServerCtxSetResult(ctxChild, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
       
  4487 	        continue;  	
       
  4488             }
       
  4489         }
       
  4490     }
       
  4491 
       
  4492     return(0);
       
  4493 }
       
  4494 
       
  4495 
       
  4496 /******************************************************************** 
       
  4497  *
       
  4498  * LocateRequest/LocateResponse
       
  4499  *
       
  4500  *******************************************************************/
       
  4501 static int  		xmlSecXkmsServerRequestLocateNodeRead	(xmlSecXkmsServerRequestId id,
       
  4502 								 xmlSecXkmsServerCtxPtr ctx,
       
  4503 								 xmlNodePtr node);
       
  4504 static int		xmlSecXkmsServerRequestLocateNodeWrite	(xmlSecXkmsServerRequestId id,
       
  4505 								 xmlSecXkmsServerCtxPtr ctx,
       
  4506 								 xmlNodePtr node);
       
  4507 static int 		xmlSecXkmsServerRequestLocateExecute	(xmlSecXkmsServerRequestId id, 
       
  4508 								 xmlSecXkmsServerCtxPtr ctx);
       
  4509 
       
  4510 static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestLocateKlass = {
       
  4511     xmlSecXkmsServerRequestLocateName,		/* const xmlChar* name; */
       
  4512     xmlSecNodeLocateRequest,			/* const xmlChar* requestNodeName; */
       
  4513     xmlSecXkmsNs,				/* const xmlChar* requestNodeNs; */
       
  4514     xmlSecNodeLocateResult,			/* const xmlChar* responseNodeName; */
       
  4515     xmlSecXkmsNs,				/* const xmlChar* responseNodeNs; */
       
  4516     XMLSEC_XKMS_SERVER_REQUEST_KLASS_ALLOWED_IN_COUMPOUND,      /* xmlSecBitMask flags; */
       
  4517     xmlSecXkmsServerRequestLocateNodeRead,	/* xmlSecXkmsServerRequestNodeReadMethod readNode; */
       
  4518     xmlSecXkmsServerRequestLocateNodeWrite,	/* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
       
  4519     xmlSecXkmsServerRequestLocateExecute,	/* xmlSecXkmsServerRequestExecuteMethod execute; */
       
  4520     NULL,                                       /* void* reserved1; */
       
  4521     NULL                                        /* void* reserved2; */
       
  4522 };
       
  4523 
       
  4524 /**
       
  4525  * xmlSecXkmsServerRequestLocateGetKlass:
       
  4526  *
       
  4527  * The LocateRequest klass.
       
  4528  *
       
  4529  * Returns LocateRequest klass.
       
  4530  */
       
  4531 EXPORT_C 
       
  4532 xmlSecXkmsServerRequestId	
       
  4533 xmlSecXkmsServerRequestLocateGetKlass(void) {
       
  4534     return(&xmlSecXkmsServerRequestLocateKlass);
       
  4535 }
       
  4536 
       
  4537 /**
       
  4538  *  <xkms:LocateRequest Id Service Nonce? OriginalRequestId? ResponseLimit?>
       
  4539  *      <ds:Signature>?
       
  4540  *      <xkms:MessageExtension>*
       
  4541  *      (<xkms:OpaqueClientData>
       
  4542  *          <xkms:OpaqueData>?
       
  4543  *      )?
       
  4544  *      <xkms:ResponseMechanism>*
       
  4545  *      <xkms:RespondWith>*
       
  4546  *      <xkms:PendingNotification Mechanism Identifier>?
       
  4547  *      <xkms:QueryKeyBinding Id?>
       
  4548  *          <ds:KeyInfo>?
       
  4549  *          <xkms:KeyUsage>?
       
  4550  *          <xkms:KeyUsage>?
       
  4551  *          <xkms:KeyUsage>?
       
  4552  *          <xkms:UseKeyWith Application Identifier>*    
       
  4553  *          <xkms:TimeInstant Time>?
       
  4554  *
       
  4555  * XML Schema:
       
  4556  *
       
  4557  *    <!-- LocateRequest -->
       
  4558  *    <element name="LocateRequest" type="xkms:LocateRequestType"/>
       
  4559  *    <complexType name="LocateRequestType">
       
  4560  *        <complexContent>
       
  4561  *            <extension base="xkms:RequestAbstractType">
       
  4562  *                <sequence>
       
  4563  *                    <element ref="xkms:QueryKeyBinding"/>
       
  4564  *                </sequence>
       
  4565  *            </extension>
       
  4566  *        </complexContent>
       
  4567  *    </complexType>
       
  4568  *    <!-- /LocateRequest -->
       
  4569  */
       
  4570 static int  
       
  4571 xmlSecXkmsServerRequestLocateNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4572     xmlNodePtr cur;
       
  4573     int ret;
       
  4574     
       
  4575     xmlSecAssert2(id == xmlSecXkmsServerRequestLocateId, -1);
       
  4576     xmlSecAssert2(ctx != NULL, -1);
       
  4577     xmlSecAssert2(node != NULL, -1);
       
  4578 
       
  4579     cur = node;
       
  4580     
       
  4581     /* first read "parent" type */
       
  4582     ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, &cur);
       
  4583     if(ret < 0) {
       
  4584     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4585 		    NULL,
       
  4586 		    "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
       
  4587 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4588 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4589 	return(-1);
       
  4590     }
       
  4591 
       
  4592     /* now read required <xkms:QueryKeyBinding/> node */
       
  4593     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeQueryKeyBinding, xmlSecXkmsNs))) {
       
  4594 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4595 		    NULL,
       
  4596 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  4597 		    XMLSEC_ERRORS_R_INVALID_NODE,
       
  4598 		    "node=%s", 
       
  4599 		    xmlSecErrorsSafeString(xmlSecNodeQueryKeyBinding));
       
  4600 	return(-1);
       
  4601     }
       
  4602     
       
  4603     /* read <xkms:QueryKeyBinding/> node */    
       
  4604     ret = xmlSecXkmsServerCtxQueryKeyBindingNodeRead(ctx, cur);
       
  4605     if(ret < 0) {
       
  4606     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4607 		    NULL,
       
  4608 		    "xmlSecXkmsServerCtxQueryKeyBindingNodeRead",
       
  4609 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4610 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4611 	return(-1);
       
  4612     }
       
  4613     cur = xmlSecGetNextElementNode(cur->next);    
       
  4614 
       
  4615     /* check that there is nothing after the last node */
       
  4616     if(cur != NULL) {
       
  4617 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4618 		    NULL,
       
  4619 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  4620 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
  4621 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4622 	return(-1);
       
  4623     }
       
  4624 
       
  4625     return(0);
       
  4626 }
       
  4627 
       
  4628 /**
       
  4629  *  <xkms:LocateResult Id Service Nonce? ResultMajor ResultMinor? RequestId?>
       
  4630  *      <ds:Signature>?
       
  4631  *      <xkms:MessageExtension>*
       
  4632  *      (<xkms:OpaqueClientData>
       
  4633  *          <xkms:OpaqueData>?
       
  4634  *      )?
       
  4635  *      <xkms:RequestSignatureValue>*
       
  4636  *      (<xkms:UnverifiedKeyBinding Id?>
       
  4637  *          <ds:KeyInfo>?
       
  4638  *          <xkms:KeyUsage>?
       
  4639  *          <xkms:KeyUsage>?
       
  4640  *          <xkms:KeyUsage>?
       
  4641  *          <xkms:UseKeyWith Application Identifier>*    
       
  4642  *          <xkms:ValidityInterval NotBefore NotOnOrAfter>?
       
  4643  *      )*
       
  4644  * 
       
  4645  * XML Schema:
       
  4646  *    <!-- LocateResult -->
       
  4647  *    <element name="LocateResult" type="xkms:LocateResultType"/>
       
  4648  *    <complexType name="LocateResultType">
       
  4649  *         <complexContent>
       
  4650  *	        <extension base="xkms:ResultType">
       
  4651  *		     <sequence>
       
  4652  *		         <element ref="xkms:UnverifiedKeyBinding" minOccurs="0" 
       
  4653  *			          maxOccurs="unbounded"/>
       
  4654  *		     </sequence>
       
  4655  *		</extension>
       
  4656  *	   </complexContent>
       
  4657  *    </complexType>
       
  4658  *    <!-- /LocateResult -->
       
  4659  */ 
       
  4660 static int 
       
  4661 xmlSecXkmsServerRequestLocateNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4662     xmlSecSize pos, size;
       
  4663     xmlSecKeyPtr key;
       
  4664     xmlNodePtr cur;
       
  4665     int ret;
       
  4666 
       
  4667     xmlSecAssert2(id == xmlSecXkmsServerRequestLocateId, -1);
       
  4668     xmlSecAssert2(ctx != NULL, -1);
       
  4669     xmlSecAssert2(node != NULL, -1);
       
  4670 
       
  4671     /* first write the "parent" type */
       
  4672     ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
       
  4673     if(ret < 0) {
       
  4674 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4675 		    NULL,
       
  4676 		    "xmlSecXkmsServerCtxResultTypeNodeWrite",
       
  4677 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4678 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4679 	return(-1);  	
       
  4680     }
       
  4681     
       
  4682     /* write keys in <xkms:UnverifiedKeyBinding> nodes */
       
  4683     size = xmlSecPtrListGetSize(&(ctx->keys));
       
  4684     for(pos = 0; pos < size; ++pos) {
       
  4685 	key = (xmlSecKeyPtr)xmlSecPtrListGetItem(&(ctx->keys), pos);
       
  4686 	if(key == NULL) {
       
  4687 	    continue;
       
  4688 	}
       
  4689             
       
  4690 	cur = xmlSecAddChild(node, xmlSecNodeUnverifiedKeyBinding, xmlSecXkmsNs);
       
  4691 	if(cur == NULL) {
       
  4692 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  4693 			NULL,
       
  4694 			"xmlSecAddChild",
       
  4695 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4696 			"node=%s",
       
  4697 			xmlSecErrorsSafeString(xmlSecNodeUnverifiedKeyBinding));
       
  4698 	    return(-1);  	
       
  4699     	}
       
  4700 
       
  4701 	ret = xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(ctx, cur, key);
       
  4702 	if(ret < 0) {
       
  4703 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  4704 			NULL,
       
  4705 			"xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite",
       
  4706 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4707 			XMLSEC_ERRORS_NO_MESSAGE);
       
  4708 	    return(-1);  	
       
  4709 	}
       
  4710     }
       
  4711 
       
  4712     return(0);
       
  4713 }
       
  4714 
       
  4715 static int 
       
  4716 xmlSecXkmsServerRequestLocateExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
       
  4717     xmlSecKeyPtr key = NULL;
       
  4718     int ret;
       
  4719     
       
  4720     xmlSecAssert2(id == xmlSecXkmsServerRequestLocateId, -1);
       
  4721     xmlSecAssert2(ctx != NULL, -1);
       
  4722 
       
  4723     /* now we are ready to search for key */
       
  4724     if((ctx->keyInfoReadCtx.keysMngr != NULL) && (ctx->keyInfoReadCtx.keysMngr->getKey != NULL)) {
       
  4725 	key = (ctx->keyInfoReadCtx.keysMngr->getKey)(ctx->keyInfoNode, &(ctx->keyInfoReadCtx));
       
  4726     }
       
  4727     
       
  4728     /* check that we got what we needed */
       
  4729     if((key == NULL) || (!xmlSecKeyMatch(key, NULL, &(ctx->keyInfoReadCtx.keyReq)))) {
       
  4730 	if(key != NULL) {
       
  4731     	    xmlSecKeyDestroy(key);
       
  4732 	}
       
  4733 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorNoMatch);
       
  4734 	return(-1);
       
  4735     } 
       
  4736         
       
  4737     xmlSecAssert2(key != NULL, -1);
       
  4738     ret = xmlSecPtrListAdd(&(ctx->keys), key);
       
  4739     if(ret < 0) {
       
  4740     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4741 		    NULL,
       
  4742 		    "xmlSecPtrListAdd",
       
  4743 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4744 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4745 	xmlSecKeyDestroy(key);
       
  4746 	return(-1);
       
  4747     }
       
  4748     
       
  4749     return(0);
       
  4750 }
       
  4751 
       
  4752 
       
  4753 /******************************************************************** 
       
  4754  *
       
  4755  * ValidateRequest/ValidateResponse
       
  4756  *
       
  4757  *******************************************************************/
       
  4758 static int  		xmlSecXkmsServerRequestValidateNodeRead	(xmlSecXkmsServerRequestId id,
       
  4759 								 xmlSecXkmsServerCtxPtr ctx,
       
  4760 								 xmlNodePtr node);
       
  4761 static int		xmlSecXkmsServerRequestValidateNodeWrite(xmlSecXkmsServerRequestId id,
       
  4762 								 xmlSecXkmsServerCtxPtr ctx,
       
  4763 								 xmlNodePtr node);
       
  4764 static int 		xmlSecXkmsServerRequestValidateExecute	(xmlSecXkmsServerRequestId id, 
       
  4765 								 xmlSecXkmsServerCtxPtr ctx);
       
  4766 
       
  4767 static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestValidateKlass = {
       
  4768     xmlSecXkmsServerRequestValidateName,	/* const xmlChar* name; */
       
  4769     xmlSecNodeValidateRequest,			/* const xmlChar* requestNodeName; */
       
  4770     xmlSecXkmsNs,				/* const xmlChar* requestNodeNs; */
       
  4771     xmlSecNodeValidateResult,			/* const xmlChar* responseNodeName; */
       
  4772     xmlSecXkmsNs,				/* const xmlChar* responseNodeNs; */
       
  4773     XMLSEC_XKMS_SERVER_REQUEST_KLASS_ALLOWED_IN_COUMPOUND,      /* xmlSecBitMask flags; */
       
  4774     xmlSecXkmsServerRequestValidateNodeRead,	/* xmlSecXkmsServerRequestNodeReadMethod readNode; */
       
  4775     xmlSecXkmsServerRequestValidateNodeWrite,	/* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
       
  4776     xmlSecXkmsServerRequestValidateExecute,	/* xmlSecXkmsServerRequestExecuteMethod execute; */
       
  4777     NULL,                                       /* void* reserved1; */
       
  4778     NULL                                        /* void* reserved2; */
       
  4779 };
       
  4780 
       
  4781 /**
       
  4782  * xmlSecXkmsServerRequestValidateGetKlass:
       
  4783  *
       
  4784  * The ValidateRequest klass.
       
  4785  *
       
  4786  * Returns ValidateRequest klass.
       
  4787  */
       
  4788 EXPORT_C 
       
  4789 xmlSecXkmsServerRequestId	
       
  4790 xmlSecXkmsServerRequestValidateGetKlass(void) {
       
  4791     return(&xmlSecXkmsServerRequestValidateKlass);
       
  4792 }
       
  4793 
       
  4794 /**
       
  4795  *  <xkms:ValidateRequest Id Service Nonce? OriginalRequestId? ResponseLimit?>
       
  4796  *      <ds:Signature>?
       
  4797  *      <xkms:MessageExtension>*
       
  4798  *      (<xkms:OpaqueClientData>
       
  4799  *          <xkms:OpaqueData>?
       
  4800  *      )?
       
  4801  *      <xkms:ResponseMechanism>*
       
  4802  *      <xkms:RespondWith>*
       
  4803  *      <xkms:PendingNotification Mechanism Identifier>?
       
  4804  *      <xkms:QueryKeyBinding Id?>
       
  4805  *          <ds:KeyInfo>?
       
  4806  *          <xkms:KeyUsage>?
       
  4807  *          <xkms:KeyUsage>?
       
  4808  *          <xkms:KeyUsage>?
       
  4809  *          <xkms:UseKeyWith Application Identifier>*    
       
  4810  *          <xkms:TimeInstant Time>?
       
  4811  * 
       
  4812  * XML Schema:
       
  4813  * 
       
  4814  *    <!-- ValidateRequest -->   
       
  4815  *    <element name="ValidateRequest" type="xkms:ValidateRequestType"/>   
       
  4816  *    <complexType name="ValidateRequestType">      
       
  4817  *        <complexContent>         
       
  4818  *            <extension base="xkms:RequestAbstractType">
       
  4819  *                <sequence>
       
  4820  *                    <element ref="xkms:QueryKeyBinding"/>
       
  4821  *                </sequence>
       
  4822  *            </extension>						         
       
  4823  *        </complexContent> 
       
  4824  *    </complexType>
       
  4825  *    <!-- /ValidateRequest -->							        
       
  4826  */
       
  4827 static int  
       
  4828 xmlSecXkmsServerRequestValidateNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4829     xmlNodePtr cur;
       
  4830     int ret;
       
  4831     
       
  4832     xmlSecAssert2(id == xmlSecXkmsServerRequestValidateId, -1);
       
  4833     xmlSecAssert2(ctx != NULL, -1);
       
  4834     xmlSecAssert2(node != NULL, -1);
       
  4835 
       
  4836     cur = node;
       
  4837     
       
  4838     /* first read "parent" type */
       
  4839     ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, &cur);
       
  4840     if(ret < 0) {
       
  4841     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4842 		    NULL,
       
  4843 		    "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
       
  4844 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4845 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4846 	return(-1);
       
  4847     }
       
  4848 
       
  4849     /* now read required <xkms:QueryKeyBinding/> node */
       
  4850     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeQueryKeyBinding, xmlSecXkmsNs))) {
       
  4851 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4852 		    NULL,
       
  4853 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  4854 		    XMLSEC_ERRORS_R_INVALID_NODE,
       
  4855 		    "node=%s", 
       
  4856 		    xmlSecErrorsSafeString(xmlSecNodeQueryKeyBinding));
       
  4857 	return(-1);
       
  4858     }
       
  4859     
       
  4860     /* read <xkms:QueryKeyBinding/> node */    
       
  4861     ret = xmlSecXkmsServerCtxQueryKeyBindingNodeRead(ctx, cur);
       
  4862     if(ret < 0) {
       
  4863     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4864 		    NULL,
       
  4865 		    "xmlSecXkmsServerCtxQueryKeyBindingNodeRead",
       
  4866 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4867 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4868 	return(-1);
       
  4869     }
       
  4870     cur = xmlSecGetNextElementNode(cur->next);    
       
  4871 
       
  4872     /* check that there is nothing after the last node */
       
  4873     if(cur != NULL) {
       
  4874 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4875 		    NULL,
       
  4876 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  4877 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
  4878 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4879 	return(-1);
       
  4880     }
       
  4881 
       
  4882     return(0);
       
  4883 }
       
  4884 
       
  4885 /**
       
  4886  *  <xkms:ValidateResult Id Service Nonce? ResultMajor ResultMinor? RequestId?>
       
  4887  *      <ds:Signature>?
       
  4888  *      <xkms:MessageExtension>*
       
  4889  *      (<xkms:OpaqueClientData>
       
  4890  *           <xkms:OpaqueData>?
       
  4891  *      )?
       
  4892  *      <xkms:RequestSignatureValue>*
       
  4893  *      (<xkms:KeyBinding Id?>
       
  4894  *          <ds:KeyInfo>?
       
  4895  *          <xkms:KeyUsage>?
       
  4896  *          <xkms:KeyUsage>?
       
  4897  *          <xkms:KeyUsage>?
       
  4898  *          <xkms:UseKeyWith Application Identifier>*    
       
  4899  *          <xkms:ValidityInterval NotBefore NotOnOrAfter>?
       
  4900  *          <xkms:Status StatusValue>
       
  4901  *              (<xkms:ValidReason>?
       
  4902  *               <xkms:IndeterminateReason>?
       
  4903  *               <xkms:InvalidReason>?
       
  4904  *              )*
       
  4905  *      )*
       
  4906  * 
       
  4907  * XML Schema:
       
  4908  *
       
  4909  *    <!-- ValidateResult -->   
       
  4910  *    <element name="ValidateResult" type="xkms:ValidateResultType"/>
       
  4911  *    <complexType name="ValidateResultType">
       
  4912  *        <complexContent>
       
  4913  *            <extension base="xkms:ResultType">
       
  4914  *                <sequence>
       
  4915  *                    <element ref="xkms:KeyBinding" minOccurs="0" 
       
  4916  *				    maxOccurs="unbounded"/>
       
  4917  *                </sequence>
       
  4918  *            </extension>
       
  4919  *        </complexContent>
       
  4920  *    </complexType>
       
  4921  *    <!-- /ValidateResult -->
       
  4922  */ 
       
  4923 static int 
       
  4924 xmlSecXkmsServerRequestValidateNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
       
  4925     xmlSecSize pos, size;
       
  4926     xmlSecKeyPtr key;
       
  4927     xmlNodePtr cur;
       
  4928     int ret;
       
  4929 
       
  4930     xmlSecAssert2(id == xmlSecXkmsServerRequestValidateId, -1);
       
  4931     xmlSecAssert2(ctx != NULL, -1);
       
  4932     xmlSecAssert2(node != NULL, -1);
       
  4933 
       
  4934     /* first write the "parent" type */
       
  4935     ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
       
  4936     if(ret < 0) {
       
  4937 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  4938 		    NULL,
       
  4939 		    "xmlSecXkmsServerCtxResultTypeNodeWrite",
       
  4940 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4941 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  4942 	return(-1);  	
       
  4943     }
       
  4944     
       
  4945     /* write keys in <xkms:UnverifiedKeyBinding> nodes */
       
  4946     size = xmlSecPtrListGetSize(&(ctx->keys));
       
  4947     for(pos = 0; pos < size; ++pos) {
       
  4948 	key = (xmlSecKeyPtr)xmlSecPtrListGetItem(&(ctx->keys), pos);
       
  4949 	if(key == NULL) {
       
  4950 	    continue;
       
  4951 	}
       
  4952             
       
  4953 	cur = xmlSecAddChild(node, xmlSecNodeUnverifiedKeyBinding, xmlSecXkmsNs);
       
  4954 	if(cur == NULL) {
       
  4955 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  4956 			NULL,
       
  4957 			"xmlSecAddChild",
       
  4958 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4959 			"node=%s",
       
  4960 			xmlSecErrorsSafeString(xmlSecNodeUnverifiedKeyBinding));
       
  4961 	    return(-1);  	
       
  4962     	}
       
  4963 
       
  4964 	ret = xmlSecXkmsServerCtxKeyBindingNodeWrite(ctx, cur, key);
       
  4965 	if(ret < 0) {
       
  4966 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  4967 			NULL,
       
  4968 			"xmlSecXkmsServerCtxKeyBindingNodeWrite",
       
  4969 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  4970 			XMLSEC_ERRORS_NO_MESSAGE);
       
  4971 	    return(-1);  	
       
  4972 	}
       
  4973     }
       
  4974 
       
  4975     return(0);
       
  4976 }
       
  4977 
       
  4978 static int 
       
  4979 xmlSecXkmsServerRequestValidateExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
       
  4980     xmlSecKeyPtr key = NULL;
       
  4981     int ret;
       
  4982     
       
  4983     xmlSecAssert2(id == xmlSecXkmsServerRequestValidateId, -1);
       
  4984     xmlSecAssert2(ctx != NULL, -1);
       
  4985 
       
  4986     /* now we are ready to search for key */
       
  4987     if((ctx->keyInfoReadCtx.keysMngr != NULL) && (ctx->keyInfoReadCtx.keysMngr->getKey != NULL)) {
       
  4988 	key = (ctx->keyInfoReadCtx.keysMngr->getKey)(ctx->keyInfoNode, &(ctx->keyInfoReadCtx));
       
  4989     }
       
  4990     
       
  4991     /* check that we got what we needed */
       
  4992     if((key == NULL) || (!xmlSecKeyMatch(key, NULL, &(ctx->keyInfoReadCtx.keyReq)))) {
       
  4993 	if(key != NULL) {
       
  4994     	    xmlSecKeyDestroy(key);
       
  4995 	}
       
  4996 	xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorNoMatch);
       
  4997 	return(-1);
       
  4998     } 
       
  4999         
       
  5000     xmlSecAssert2(key != NULL, -1);
       
  5001     ret = xmlSecPtrListAdd(&(ctx->keys), key);
       
  5002     if(ret < 0) {
       
  5003     	xmlSecError(XMLSEC_ERRORS_HERE,
       
  5004 		    NULL,
       
  5005 		    "xmlSecPtrListAdd",
       
  5006 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  5007 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  5008 	xmlSecKeyDestroy(key);
       
  5009 	return(-1);
       
  5010     }
       
  5011     
       
  5012     return(0);
       
  5013 }
       
  5014 
       
  5015 #endif /* XMLSEC_NO_XKMS */
       
  5016