xmlsecurityengine/xmlsec/src/xmlsec_keys.c
changeset 0 e35f40988205
child 16 d10d750052f0
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /** 
       
     2  * XML Security Library (http://www.aleksey.com/xmlsec).
       
     3  *
       
     4  * Keys.
       
     5  *
       
     6  * This is free software; see Copyright file in the source
       
     7  * distribution for preciese wording.
       
     8  * 
       
     9  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
       
    10  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    11  */
       
    12 #include "xmlsec_globals.h"
       
    13 
       
    14 #include <stdlib.h>
       
    15 #include <string.h>
       
    16  
       
    17 #include <libxml2_tree.h>
       
    18 #include <libxml2_globals.h>
       
    19 
       
    20 #include "xmlsec_xmlsec.h"
       
    21 #include "xmlsec_xmltree.h"
       
    22 #include "xmlsec_list.h"
       
    23 #include "xmlsec_keys.h"
       
    24 #include "xmlsec_keysmngr.h"
       
    25 #include "xmlsec_transforms.h"
       
    26 #include "xmlsec_keyinfo.h"
       
    27 #include "xmlsec_errors.h"
       
    28 
       
    29 /**************************************************************************
       
    30  *
       
    31  * xmlSecKeyUseWith
       
    32  *
       
    33  *************************************************************************/
       
    34 /** 
       
    35  * xmlSecKeyUseWithInitialize:
       
    36  * @keyUseWith:         the pointer to information about key application/user.
       
    37  * 
       
    38  * Initializes @keyUseWith object.
       
    39  *
       
    40  * Returns 0 on success or a negative value if an error occurs.
       
    41  */
       
    42 EXPORT_C
       
    43 int 
       
    44 xmlSecKeyUseWithInitialize(xmlSecKeyUseWithPtr keyUseWith) {
       
    45     xmlSecAssert2(keyUseWith != NULL, -1);
       
    46 
       
    47     memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
       
    48     return(0);
       
    49 }
       
    50 
       
    51 /** 
       
    52  * xmlSecKeyUseWithFinalize:
       
    53  * @keyUseWith:         the pointer to information about key application/user.
       
    54  *
       
    55  * Finalizes @keyUseWith object.
       
    56  */
       
    57 EXPORT_C
       
    58 void 
       
    59 xmlSecKeyUseWithFinalize(xmlSecKeyUseWithPtr keyUseWith) {
       
    60     xmlSecAssert(keyUseWith != NULL);
       
    61     
       
    62     xmlSecKeyUseWithReset(keyUseWith);
       
    63     memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
       
    64 }
       
    65 
       
    66 /** 
       
    67  * xmlSecKeyUseWithReset:
       
    68  * @keyUseWith:         the pointer to information about key application/user.
       
    69  * 
       
    70  * Resets the @keyUseWith to its state after initialization.
       
    71  */
       
    72 EXPORT_C
       
    73 void 
       
    74 xmlSecKeyUseWithReset(xmlSecKeyUseWithPtr keyUseWith) {
       
    75     xmlSecAssert(keyUseWith != NULL);
       
    76 
       
    77     xmlSecKeyUseWithSet(keyUseWith, NULL, NULL);
       
    78 }
       
    79 
       
    80 /** 
       
    81  * xmlSecKeyUseWithCopy:
       
    82  * @dst:         the pointer to destination object.
       
    83  * @src:         the pointer to source object.
       
    84  *
       
    85  * Copies information from @dst to @src.
       
    86  *
       
    87  * Returns 0 on success or a negative value if an error occurs.
       
    88  */
       
    89 EXPORT_C
       
    90 int 
       
    91 xmlSecKeyUseWithCopy(xmlSecKeyUseWithPtr dst, xmlSecKeyUseWithPtr src) {
       
    92     xmlSecAssert2(dst != NULL, -1);
       
    93     xmlSecAssert2(src != NULL, -1);
       
    94     
       
    95     return(xmlSecKeyUseWithSet(dst, src->application, src->identifier));
       
    96 }
       
    97 
       
    98 /** 
       
    99  * xmlSecKeyUseWithCreate:
       
   100  * @keyUseWith:         the pointer to information about key application/user.
       
   101  * @application:        the application value.
       
   102  * @identifier:         the identifier value.
       
   103  *
       
   104  * Creates new xmlSecKeyUseWith object. The caller is responsible for destroying
       
   105  * returned object with @xmlSecKeyUseWithDestroy function.
       
   106  *
       
   107  * Returns pointer to newly created object or NULL if an error occurs.
       
   108  */
       
   109 EXPORT_C
       
   110 xmlSecKeyUseWithPtr 
       
   111 xmlSecKeyUseWithCreate(const xmlChar* application, const xmlChar* identifier) {
       
   112     xmlSecKeyUseWithPtr keyUseWith;
       
   113     int ret;
       
   114 
       
   115     /* Allocate a new xmlSecKeyUseWith and fill the fields. */
       
   116     keyUseWith = (xmlSecKeyUseWithPtr)xmlMalloc(sizeof(xmlSecKeyUseWith));
       
   117     if(keyUseWith == NULL) {
       
   118 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   119 		    NULL,
       
   120 		    NULL,
       
   121 		    XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   122 		    "sizeof(xmlSecKeyUseWith)=%d", 
       
   123 		    sizeof(xmlSecKeyUseWith));
       
   124 	return(NULL);
       
   125     }
       
   126     memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));    
       
   127 
       
   128     ret = xmlSecKeyUseWithInitialize(keyUseWith);
       
   129     if(ret < 0) {
       
   130     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   131 		    NULL,
       
   132 		    "xmlSecKeyUseWithInitialize",
       
   133 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   134 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   135         xmlSecKeyUseWithDestroy(keyUseWith);
       
   136         return(NULL);        
       
   137     }
       
   138 
       
   139     ret = xmlSecKeyUseWithSet(keyUseWith, application, identifier);
       
   140     if(ret < 0) {
       
   141     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   142 		    NULL,
       
   143 		    "xmlSecKeyUseWithSet",
       
   144 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   145 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   146         xmlSecKeyUseWithDestroy(keyUseWith);
       
   147         return(NULL);        
       
   148     }
       
   149 
       
   150     return(keyUseWith);
       
   151 }
       
   152 
       
   153 /** 
       
   154  * xmlSecKeyUseWithDuplicate:
       
   155  * @keyUseWith:         the pointer to information about key application/user.
       
   156  *
       
   157  * Duplicates @keyUseWith object. The caller is responsible for destroying
       
   158  * returned object with @xmlSecKeyUseWithDestroy function.
       
   159  *
       
   160  * Returns pointer to newly created object or NULL if an error occurs.
       
   161  */
       
   162 EXPORT_C
       
   163 xmlSecKeyUseWithPtr 
       
   164 xmlSecKeyUseWithDuplicate(xmlSecKeyUseWithPtr keyUseWith) {
       
   165     int ret;
       
   166 
       
   167     xmlSecKeyUseWithPtr newKeyUseWith;
       
   168 
       
   169     xmlSecAssert2(keyUseWith != NULL, NULL);
       
   170 
       
   171     newKeyUseWith = xmlSecKeyUseWithCreate(NULL, NULL);
       
   172     if(newKeyUseWith == NULL) {
       
   173     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   174 		    NULL,
       
   175 		    "xmlSecKeyUseWithCreate",
       
   176 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   177 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   178         return(NULL);        
       
   179     }
       
   180 
       
   181     ret = xmlSecKeyUseWithCopy(newKeyUseWith, keyUseWith);
       
   182     if(ret < 0) {
       
   183     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   184 		    NULL,
       
   185 		    "xmlSecKeyUseWithCopy",
       
   186 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   187 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   188         xmlSecKeyUseWithDestroy(keyUseWith);
       
   189         return(NULL);        
       
   190     }
       
   191 
       
   192     return(newKeyUseWith);
       
   193 }
       
   194 
       
   195 /** 
       
   196  * xmlSecKeyUseWithDestroy:
       
   197  * @keyUseWith:         the pointer to information about key application/user.
       
   198  *
       
   199  * Destroys @keyUseWith created with @xmlSecKeyUseWithCreate or @xmlSecKeyUseWithDuplicate
       
   200  * functions.
       
   201  */
       
   202 EXPORT_C
       
   203 void 
       
   204 xmlSecKeyUseWithDestroy(xmlSecKeyUseWithPtr keyUseWith) {
       
   205     xmlSecAssert(keyUseWith != NULL);
       
   206 
       
   207     xmlSecKeyUseWithFinalize(keyUseWith);
       
   208     xmlFree(keyUseWith);
       
   209 }
       
   210 
       
   211 /** 
       
   212  * xmlSecKeyUseWithSet:
       
   213  * @keyUseWith:         the pointer to information about key application/user.
       
   214  * @application:        the new application value.
       
   215  * @identifier:         the new identifier value.
       
   216  * 
       
   217  * Sets @application and @identifier in the @keyUseWith.
       
   218  *
       
   219  * Returns 0 on success or a negative value if an error occurs.
       
   220  */
       
   221 EXPORT_C
       
   222 int 
       
   223 xmlSecKeyUseWithSet(xmlSecKeyUseWithPtr keyUseWith, const xmlChar* application, const xmlChar* identifier) {
       
   224     xmlSecAssert2(keyUseWith != NULL, -1);
       
   225     
       
   226     if(keyUseWith->application != NULL) {
       
   227 	xmlFree(keyUseWith->application); 
       
   228 	keyUseWith->application = NULL;
       
   229     }
       
   230     if(keyUseWith->identifier != NULL) {
       
   231 	xmlFree(keyUseWith->identifier); 
       
   232 	keyUseWith->identifier = NULL;
       
   233     }
       
   234     
       
   235     if(application != NULL) {
       
   236 	keyUseWith->application = xmlStrdup(application);
       
   237 	if(keyUseWith->application == NULL) {
       
   238     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   239 		        NULL,
       
   240 			NULL,
       
   241 		        XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   242 			"xmlStrlen(application)=%d", 
       
   243 			xmlStrlen(application));
       
   244 	    return(-1);
       
   245 	}
       
   246     }
       
   247     if(identifier != NULL) {
       
   248 	keyUseWith->identifier = xmlStrdup(identifier);
       
   249 	if(keyUseWith->identifier == NULL) {
       
   250     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   251 		        NULL,
       
   252 			NULL,
       
   253 		        XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   254 			"xmlStrlen(identifier)=%d", 
       
   255 			xmlStrlen(identifier));
       
   256 	    return(-1);
       
   257 	}
       
   258     }
       
   259     
       
   260     return(0);
       
   261 }
       
   262 
       
   263 /** 
       
   264  * xmlSecKeyUseWithDebugDump:
       
   265  * @keyUseWith:         the pointer to information about key application/user.
       
   266  * @output:             the pointer to output FILE.
       
   267  *
       
   268  * Prints xmlSecKeyUseWith debug information to a file @output.
       
   269  */
       
   270 EXPORT_C
       
   271 void 
       
   272 xmlSecKeyUseWithDebugDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
       
   273     xmlSecAssert(keyUseWith != NULL);
       
   274     xmlSecAssert(output != NULL);
       
   275 
       
   276     fprintf(output, "=== KeyUseWith: application=\"%s\",identifier=\"%s\"\n", 
       
   277                 (keyUseWith->application) ? keyUseWith->application : BAD_CAST "",
       
   278                 (keyUseWith->identifier) ? keyUseWith->identifier : BAD_CAST "");    
       
   279 }
       
   280 
       
   281 /** 
       
   282  * xmlSecKeyUseWithDebugXmlDump:
       
   283  * @keyUseWith:         the pointer to information about key application/user.
       
   284  * @output:             the pointer to output FILE.
       
   285  *
       
   286  * Prints xmlSecKeyUseWith debug information to a file @output in XML format.
       
   287  */
       
   288 EXPORT_C
       
   289 void 
       
   290 xmlSecKeyUseWithDebugXmlDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
       
   291     xmlSecAssert(keyUseWith != NULL);
       
   292     xmlSecAssert(output != NULL);
       
   293 
       
   294     fprintf(output, "<KeyUseWith>\n");
       
   295     fprintf(output, "<Application>%s</Application>", 
       
   296         (keyUseWith->application) ? keyUseWith->application : BAD_CAST "");
       
   297     fprintf(output, "<Identifier>%s</Identifier>", 
       
   298         (keyUseWith->identifier) ? keyUseWith->identifier : BAD_CAST "");
       
   299     fprintf(output, "</KeyUseWith>\n");
       
   300 }
       
   301 
       
   302 /***********************************************************************
       
   303  *
       
   304  * KeyUseWith list
       
   305  *
       
   306  **********************************************************************/
       
   307 static xmlSecPtrListKlass xmlSecKeyUseWithPtrListKlass = {
       
   308     BAD_CAST "key-use-with-list",
       
   309     (xmlSecPtrDuplicateItemMethod)xmlSecKeyUseWithDuplicate, 	/* xmlSecPtrDuplicateItemMethod duplicateItem; */
       
   310     (xmlSecPtrDestroyItemMethod)xmlSecKeyUseWithDestroy,	/* xmlSecPtrDestroyItemMethod destroyItem; */
       
   311     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugDump,	/* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
       
   312     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugXmlDump,	/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
       
   313 };
       
   314 
       
   315 /**
       
   316  * xmlSecKeyUseWithPtrListGetKlass:
       
   317  * 
       
   318  * The key data list klass.
       
   319  *
       
   320  * Returns pointer to the key data list klass.
       
   321  */
       
   322 EXPORT_C
       
   323 xmlSecPtrListId 
       
   324 xmlSecKeyUseWithPtrListGetKlass(void) {
       
   325     return(&xmlSecKeyUseWithPtrListKlass);
       
   326 }
       
   327 
       
   328 /**************************************************************************
       
   329  *
       
   330  * xmlSecKeyReq - what key are we looking for?
       
   331  *
       
   332  *************************************************************************/
       
   333 /** 
       
   334  * xmlSecKeyReqInitialize:
       
   335  * @keyReq:		the pointer to key requirements object.
       
   336  *
       
   337  * Initialize key requirements object. Caller is responsible for
       
   338  * cleaning it with #xmlSecKeyReqFinalize function.
       
   339  *
       
   340  * Returns 0 on success or a negative value if an error occurs.
       
   341  */
       
   342 EXPORT_C
       
   343 int 
       
   344 xmlSecKeyReqInitialize(xmlSecKeyReqPtr keyReq) {
       
   345     int ret;
       
   346     
       
   347     xmlSecAssert2(keyReq != NULL, -1);
       
   348     
       
   349     memset(keyReq, 0, sizeof(xmlSecKeyReq));
       
   350     
       
   351     keyReq->keyUsage	= xmlSecKeyUsageAny;	/* by default you can do whatever you want with the key */
       
   352     ret = xmlSecPtrListInitialize(&keyReq->keyUseWithList, xmlSecKeyUseWithPtrListId);    
       
   353     if(ret < 0) {
       
   354     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   355 		    NULL,
       
   356 		    "xmlSecPtrListInitialize",
       
   357 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   358 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   359 	return(-1);
       
   360     }
       
   361 
       
   362     
       
   363     return(0);
       
   364 }
       
   365 
       
   366 /**
       
   367  * xmlSecKeyReqFinalize:
       
   368  * @keyReq:		the pointer to key requirements object.
       
   369  *
       
   370  * Cleans the key requirements object initialized with #xmlSecKeyReqInitialize
       
   371  * function.
       
   372  */
       
   373 EXPORT_C
       
   374 void
       
   375 xmlSecKeyReqFinalize(xmlSecKeyReqPtr keyReq) {
       
   376     xmlSecAssert(keyReq != NULL);
       
   377 
       
   378     xmlSecPtrListFinalize(&keyReq->keyUseWithList);    
       
   379     memset(keyReq, 0, sizeof(xmlSecKeyReq));
       
   380 }
       
   381 
       
   382 /** 
       
   383  * xmlSecKeyReqReset:
       
   384  * @keyReq:		the pointer to key requirements object.
       
   385  *
       
   386  * Resets key requirements object for new key search.
       
   387  */
       
   388 EXPORT_C
       
   389 void 
       
   390 xmlSecKeyReqReset(xmlSecKeyReqPtr keyReq) {
       
   391     xmlSecAssert(keyReq != NULL);
       
   392 
       
   393     xmlSecPtrListEmpty(&keyReq->keyUseWithList);
       
   394     keyReq->keyId	= NULL;
       
   395     keyReq->keyType	= 0;
       
   396     keyReq->keyUsage	= xmlSecKeyUsageAny;
       
   397     keyReq->keyBitsSize	= 0;
       
   398 }
       
   399 
       
   400 /**
       
   401  * xmlSecKeyReqCopy:
       
   402  * @dst:		the pointer to destination object.
       
   403  * @src:		the pointer to source object.
       
   404  *
       
   405  * Copies key requirements from @src object to @dst object.
       
   406  * 
       
   407  * Returns 0 on success and a negative value if an error occurs.
       
   408  */
       
   409 EXPORT_C
       
   410 int 
       
   411 xmlSecKeyReqCopy(xmlSecKeyReqPtr dst, xmlSecKeyReqPtr src) {
       
   412     int ret;
       
   413     
       
   414     xmlSecAssert2(dst != NULL, -1);
       
   415     xmlSecAssert2(src != NULL, -1);
       
   416 
       
   417     dst->keyId		= src->keyId;
       
   418     dst->keyType	= src->keyType;
       
   419     dst->keyUsage	= src->keyUsage;
       
   420     dst->keyBitsSize	= src->keyBitsSize;
       
   421 
       
   422     ret = xmlSecPtrListCopy(&dst->keyUseWithList, &src->keyUseWithList);
       
   423     if(ret < 0) {
       
   424     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   425 		    NULL,
       
   426 		    "xmlSecPtrListCopy",
       
   427 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   428 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   429 	return(-1);
       
   430     }
       
   431 
       
   432     return(0);
       
   433 }
       
   434 
       
   435 /**
       
   436  * xmlSecKeyReqMatchKey:
       
   437  * @keyReq:		the pointer to key requirements object.
       
   438  * @key:		the pointer to key.
       
   439  *
       
   440  * Checks whether @key matches key requirements @keyReq.
       
   441  *
       
   442  * Returns 1 if key matches requirements, 0 if not and a negative value
       
   443  * if an error occurs.
       
   444  */
       
   445 EXPORT_C
       
   446 int 
       
   447 xmlSecKeyReqMatchKey(xmlSecKeyReqPtr keyReq, xmlSecKeyPtr key) {
       
   448     xmlSecAssert2(keyReq != NULL, -1);
       
   449     xmlSecAssert2(xmlSecKeyIsValid(key), -1);
       
   450 
       
   451     if((keyReq->keyType != xmlSecKeyDataTypeUnknown) && ((xmlSecKeyGetType(key) & keyReq->keyType) == 0)) {
       
   452 	 return(0);
       
   453     }
       
   454     if((keyReq->keyUsage != xmlSecKeyDataUsageUnknown) && ((keyReq->keyUsage & key->usage) == 0)) {
       
   455 	return(0);
       
   456     }
       
   457 
       
   458     return(xmlSecKeyReqMatchKeyValue(keyReq, xmlSecKeyGetValue(key)));
       
   459 }
       
   460 
       
   461 /**
       
   462  * xmlSecKeyReqMatchKeyValue:
       
   463  * @keyReq:		the pointer to key requirements.
       
   464  * @value:		the pointer to key value.
       
   465  *
       
   466  * Checks whether @keyValue matches key requirements @keyReq.
       
   467  *
       
   468  * Returns 1 if key value matches requirements, 0 if not and a negative value
       
   469  * if an error occurs.
       
   470  */
       
   471 EXPORT_C
       
   472 int 
       
   473 xmlSecKeyReqMatchKeyValue(xmlSecKeyReqPtr keyReq, xmlSecKeyDataPtr value) {
       
   474     xmlSecAssert2(keyReq != NULL, -1);
       
   475     xmlSecAssert2(value != NULL, -1);
       
   476     
       
   477     if((keyReq->keyId != xmlSecKeyDataIdUnknown) && 
       
   478        (!xmlSecKeyDataCheckId(value, keyReq->keyId))) {
       
   479 
       
   480 	return(0);
       
   481     }
       
   482     if((keyReq->keyBitsSize > 0) && 
       
   483        (xmlSecKeyDataGetSize(value) > 0) && 
       
   484        (xmlSecKeyDataGetSize(value) < keyReq->keyBitsSize)) {
       
   485 	
       
   486 	return(0);
       
   487     }
       
   488     return(1);
       
   489 }
       
   490 
       
   491 /** 
       
   492  * xmlSecKeyReqDebugDump:
       
   493  * @keyReq:		the pointer to key requirements object.
       
   494  * @output: 		the pointer to output FILE.
       
   495  *
       
   496  * Prints debug information about @keyReq into @output.
       
   497  */
       
   498 EXPORT_C 
       
   499 void 
       
   500 xmlSecKeyReqDebugDump(xmlSecKeyReqPtr keyReq, FILE* output) {
       
   501     xmlSecAssert(keyReq != NULL);
       
   502     xmlSecAssert(output != NULL);
       
   503 
       
   504     fprintf(output, "=== KeyReq:\n");
       
   505     fprintf(output, "==== keyId: %s\n", 
       
   506 	    (xmlSecKeyDataKlassGetName(keyReq->keyId)) ? 
       
   507 		xmlSecKeyDataKlassGetName(keyReq->keyId) : 
       
   508 		BAD_CAST "NULL");
       
   509     fprintf(output, "==== keyType: 0x%08x\n", keyReq->keyType);
       
   510     fprintf(output, "==== keyUsage: 0x%08x\n", keyReq->keyUsage);
       
   511     fprintf(output, "==== keyBitsSize: %d\n", keyReq->keyBitsSize);
       
   512     xmlSecPtrListDebugDump(&(keyReq->keyUseWithList), output);
       
   513 }
       
   514 
       
   515 /** 
       
   516  * xmlSecKeyReqDebugXmlDump:
       
   517  * @keyReq:		the pointer to key requirements object.
       
   518  * @output: 		the pointer to output FILE.
       
   519  *
       
   520  * Prints debug information about @keyReq into @output in XML format.
       
   521  */
       
   522 EXPORT_C 
       
   523 void 
       
   524 xmlSecKeyReqDebugXmlDump(xmlSecKeyReqPtr keyReq, FILE* output) {
       
   525     xmlSecAssert(keyReq != NULL);
       
   526     xmlSecAssert(output != NULL);
       
   527 
       
   528     fprintf(output, "<KeyReq>\n");
       
   529     fprintf(output, "<KeyId>%s</KeyId>\n", 
       
   530 	    (xmlSecKeyDataKlassGetName(keyReq->keyId)) ? 
       
   531 		xmlSecKeyDataKlassGetName(keyReq->keyId) : 
       
   532 		BAD_CAST "NULL");
       
   533     fprintf(output, "<KeyType>0x%08x</KeyType>\n", keyReq->keyType);
       
   534     fprintf(output, "<KeyUsage>0x%08x</KeyUsage>\n", keyReq->keyUsage);
       
   535     fprintf(output, "<KeyBitsSize>%d</KeyBitsSize>\n", keyReq->keyBitsSize);
       
   536     xmlSecPtrListDebugXmlDump(&(keyReq->keyUseWithList), output);
       
   537     fprintf(output, "</KeyReq>\n");
       
   538 }
       
   539 
       
   540 
       
   541 /**************************************************************************
       
   542  *
       
   543  * xmlSecKey
       
   544  *
       
   545  *************************************************************************/
       
   546 /**
       
   547  * xmlSecKeyCreate:
       
   548  *
       
   549  * Allocates and initializes new key. Caller is responsible for 
       
   550  * freeing returned object with #xmlSecKeyDestroy function.
       
   551  *
       
   552  * Returns the pointer to newly allocated @xmlSecKey structure
       
   553  * or NULL if an error occurs.
       
   554  */
       
   555 EXPORT_C
       
   556 xmlSecKeyPtr	
       
   557 xmlSecKeyCreate(void)  {
       
   558     xmlSecKeyPtr key;
       
   559     
       
   560     /* Allocate a new xmlSecKey and fill the fields. */
       
   561     key = (xmlSecKeyPtr)xmlMalloc(sizeof(xmlSecKey));
       
   562     if(key == NULL) {
       
   563 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   564 		    NULL,
       
   565 		    NULL,
       
   566 		    XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   567 		    "sizeof(xmlSecKey)=%d", 
       
   568 		    sizeof(xmlSecKey));
       
   569 	return(NULL);
       
   570     }
       
   571     memset(key, 0, sizeof(xmlSecKey));    
       
   572     key->usage = xmlSecKeyUsageAny;	
       
   573     return(key);
       
   574 }
       
   575 
       
   576 /**
       
   577  * xmlSecKeyEmpty:
       
   578  * @key:		the pointer to key.
       
   579  *
       
   580  * Clears the @key data.
       
   581  */
       
   582 EXPORT_C
       
   583 void
       
   584 xmlSecKeyEmpty(xmlSecKeyPtr key) {
       
   585     xmlSecAssert(key != NULL);    
       
   586     
       
   587     if(key->value != NULL) {
       
   588 	xmlSecKeyDataDestroy(key->value);
       
   589     }
       
   590     if(key->name != NULL) {
       
   591 	xmlFree(key->name);
       
   592     }
       
   593     if(key->dataList != NULL) {
       
   594 	xmlSecPtrListDestroy(key->dataList);
       
   595     }
       
   596     
       
   597     memset(key, 0, sizeof(xmlSecKey));
       
   598 }
       
   599 
       
   600 /**
       
   601  * xmlSecKeyDestroy:
       
   602  * @key: 		the pointer to key.
       
   603  *
       
   604  * Destroys the key created using #xmlSecKeyCreate function. 
       
   605  */
       
   606 EXPORT_C
       
   607 void
       
   608 xmlSecKeyDestroy(xmlSecKeyPtr key) {
       
   609     xmlSecAssert(key != NULL);    
       
   610 
       
   611     xmlSecKeyEmpty(key);
       
   612     xmlFree(key);
       
   613 }
       
   614 
       
   615 /** 
       
   616  * xmlSecKeyCopy:
       
   617  * @keyDst:		the destination key.
       
   618  * @keySrc:		the source key.
       
   619  *
       
   620  * Copies key data from @keySrc to @keyDst.
       
   621  *
       
   622  * Returns 0 on success or a negative value if an error occurs.
       
   623  */
       
   624 EXPORT_C
       
   625 int 
       
   626 xmlSecKeyCopy(xmlSecKeyPtr keyDst, xmlSecKeyPtr keySrc) {
       
   627     xmlSecAssert2(keyDst != NULL, -1);    
       
   628     xmlSecAssert2(keySrc != NULL, -1);    
       
   629     
       
   630     /* empty destination */
       
   631     xmlSecKeyEmpty(keyDst);
       
   632 
       
   633     /* copy everything */    
       
   634     if(keySrc->name != NULL) {
       
   635 	keyDst->name = xmlStrdup(keySrc->name);
       
   636 	if(keyDst->name == NULL) {
       
   637 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   638 			NULL,
       
   639 			NULL,
       
   640 		        XMLSEC_ERRORS_R_STRDUP_FAILED,
       
   641 			"len=%d", xmlStrlen(keySrc->name));
       
   642 	    return(-1);	
       
   643         }
       
   644     }
       
   645 
       
   646     if(keySrc->value != NULL) {
       
   647 	keyDst->value = xmlSecKeyDataDuplicate(keySrc->value);
       
   648 	if(keyDst->value == NULL) {
       
   649 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   650 			NULL,
       
   651 			"xmlSecKeyDataDuplicate",
       
   652 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   653 			XMLSEC_ERRORS_NO_MESSAGE);
       
   654 	    return(-1);	
       
   655         }
       
   656     }
       
   657     
       
   658     if(keySrc->dataList != NULL) {
       
   659 	keyDst->dataList = xmlSecPtrListDuplicate(keySrc->dataList);
       
   660 	if(keyDst->dataList == NULL) {
       
   661 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   662 			NULL,
       
   663 			"xmlSecPtrListDuplicate",
       
   664 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   665 			XMLSEC_ERRORS_NO_MESSAGE);
       
   666 	    return(-1);
       
   667         }
       
   668     }
       
   669     
       
   670     keyDst->usage 	   = keySrc->usage;
       
   671     keyDst->notValidBefore = keySrc->notValidBefore;
       
   672     keyDst->notValidAfter  = keySrc->notValidAfter;
       
   673     return(0);
       
   674 }
       
   675 
       
   676 /**
       
   677  * xmlSecKeyDuplicate:
       
   678  * @key: 		the pointer to the #xmlSecKey structure.
       
   679  *
       
   680  * Creates a duplicate of the given @key.
       
   681  *
       
   682  * Returns the pointer to newly allocated #xmlSecKey structure
       
   683  * or NULL if an error occurs.
       
   684  */
       
   685 EXPORT_C
       
   686 xmlSecKeyPtr	
       
   687 xmlSecKeyDuplicate(xmlSecKeyPtr key) {
       
   688     xmlSecKeyPtr newKey;
       
   689     int ret;
       
   690     
       
   691     xmlSecAssert2(key != NULL, NULL);
       
   692     
       
   693     newKey = xmlSecKeyCreate();
       
   694     if(newKey == NULL) {
       
   695 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   696 		    NULL,
       
   697 		    "xmlSecKeyCreate",
       
   698 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   699 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   700 	return(NULL);	
       
   701     }
       
   702     
       
   703     ret = xmlSecKeyCopy(newKey, key);
       
   704     if(ret < 0) {
       
   705 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   706 		    NULL,
       
   707 		    "xmlSecKeyCopy",
       
   708 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   709 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   710 	xmlSecKeyDestroy(newKey);
       
   711 	return(NULL);	
       
   712     }
       
   713     
       
   714     return(newKey);
       
   715 }
       
   716 
       
   717 /**
       
   718  * xmlSecKeyMatch:
       
   719  * @key: 		the pointer to key.
       
   720  * @name: 		the pointer to key name (may be NULL).
       
   721  * @keyReq:		the pointer to key requirements.
       
   722  * 
       
   723  * Checks whether the @key matches the given criteria.
       
   724  *
       
   725  * Returns 1 if the key satisfies the given criteria or 0 otherwise.
       
   726  */
       
   727 EXPORT_C
       
   728 int
       
   729 xmlSecKeyMatch(xmlSecKeyPtr key, const xmlChar *name, xmlSecKeyReqPtr keyReq) {
       
   730     xmlSecAssert2(xmlSecKeyIsValid(key), -1);
       
   731     xmlSecAssert2(keyReq != NULL, -1);
       
   732     
       
   733     if((name != NULL) && (!xmlStrEqual(xmlSecKeyGetName(key), name))) {
       
   734 	return(0);
       
   735     }
       
   736     return(xmlSecKeyReqMatchKey(keyReq, key));
       
   737 }
       
   738 
       
   739 /** 
       
   740  * xmlSecKeyGetType:
       
   741  * @key:		the pointer to key.
       
   742  *
       
   743  * Gets @key type.
       
   744  *
       
   745  * Returns key type.
       
   746  */
       
   747 EXPORT_C
       
   748 xmlSecKeyDataType 
       
   749 xmlSecKeyGetType(xmlSecKeyPtr key) {
       
   750     xmlSecKeyDataPtr data;
       
   751     
       
   752     xmlSecAssert2(key != NULL, xmlSecKeyDataTypeUnknown);
       
   753 
       
   754     data = xmlSecKeyGetValue(key);
       
   755     if(data == NULL) {
       
   756 	return(xmlSecKeyDataTypeUnknown);
       
   757     }
       
   758     return(xmlSecKeyDataGetType(data));
       
   759 }
       
   760 
       
   761 /** 
       
   762  * xmlSecKeyGetName:
       
   763  * @key:		the pointer to key.
       
   764  *
       
   765  * Gets key name (see also #xmlSecKeySetName function).
       
   766  *
       
   767  * Returns key name.
       
   768  */
       
   769 EXPORT_C
       
   770 const xmlChar*	
       
   771 xmlSecKeyGetName(xmlSecKeyPtr key) {
       
   772     xmlSecAssert2(key != NULL, NULL);
       
   773 
       
   774     return(key->name);
       
   775 }
       
   776 
       
   777 /** 
       
   778  * xmlSecKeySetName:
       
   779  * @key:		the pointer to key.
       
   780  * @name:		the new key name.
       
   781  *
       
   782  * Sets key name (see also #xmlSecKeyGetName function).
       
   783  *
       
   784  * Returns 0 on success or a negative value if an error occurs.
       
   785  */
       
   786 EXPORT_C
       
   787 int 
       
   788 xmlSecKeySetName(xmlSecKeyPtr key, const xmlChar* name) {
       
   789     xmlSecAssert2(key != NULL, -1);
       
   790 
       
   791     if(key->name != NULL) {
       
   792 	xmlFree(key->name);
       
   793 	key->name = NULL;
       
   794     }
       
   795     
       
   796     if(name != NULL) {
       
   797 	key->name = xmlStrdup(name);
       
   798 	if(key->name == NULL) {
       
   799 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   800 			NULL,
       
   801 			NULL,
       
   802 		        XMLSEC_ERRORS_R_STRDUP_FAILED,
       
   803 			"len=%d", xmlStrlen(name));
       
   804 	    return(-1);	    
       
   805 	}	
       
   806     }
       
   807     
       
   808     return(0);
       
   809 }
       
   810 
       
   811 /** 
       
   812  * xmlSecKeyGetValue:
       
   813  * @key:		the pointer to key.
       
   814  *
       
   815  * Gets key value (see also #xmlSecKeySetValue function).
       
   816  *
       
   817  * Returns key value (crypto material).
       
   818  */
       
   819 EXPORT_C
       
   820 xmlSecKeyDataPtr 
       
   821 xmlSecKeyGetValue(xmlSecKeyPtr key) {
       
   822     xmlSecAssert2(key != NULL, NULL);
       
   823 
       
   824     return(key->value);
       
   825 }
       
   826 
       
   827 /** 
       
   828  * xmlSecKeySetValue:
       
   829  * @key:		the pointer to key.
       
   830  * @value:		the new value.
       
   831  *
       
   832  * Sets key value (see also #xmlSecKeyGetValue function).
       
   833  *
       
   834  * Returns 0 on success or a negative value if an error occurs.
       
   835  */
       
   836 EXPORT_C
       
   837 int 
       
   838 xmlSecKeySetValue(xmlSecKeyPtr key, xmlSecKeyDataPtr value) {
       
   839     xmlSecAssert2(key != NULL, -1);
       
   840 
       
   841     if(key->value != NULL) {
       
   842 	xmlSecKeyDataDestroy(key->value);
       
   843 	key->value = NULL;
       
   844     }
       
   845     key->value = value;
       
   846     
       
   847     return(0);
       
   848 }
       
   849 
       
   850 /** 
       
   851  * xmlSecKeyGetData:
       
   852  * @key:		the pointer to key.
       
   853  * @dataId:		the requested data klass.
       
   854  *
       
   855  * Gets key's data.
       
   856  *
       
   857  * Returns additional data associated with the @key (see also 
       
   858  * #xmlSecKeyAdoptData function).
       
   859  */
       
   860 EXPORT_C
       
   861 xmlSecKeyDataPtr 
       
   862 xmlSecKeyGetData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
       
   863     
       
   864     xmlSecAssert2(key != NULL, NULL);
       
   865     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
       
   866 
       
   867     /* special cases */
       
   868     if(dataId == xmlSecKeyDataValueId) {
       
   869 	return(key->value);
       
   870     } else if(key->dataList != NULL) {
       
   871 	xmlSecKeyDataPtr tmp;
       
   872 	xmlSecSize pos, size;
       
   873 	
       
   874 	size = xmlSecPtrListGetSize(key->dataList);
       
   875 	for(pos = 0; pos < size; ++pos) {
       
   876 	    tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
       
   877 	    if((tmp != NULL) && (tmp->id == dataId)) {	
       
   878 		return(tmp);
       
   879 	    }
       
   880 	}
       
   881     }
       
   882     return(NULL);
       
   883 }
       
   884 
       
   885 /**
       
   886  * xmlSecKeyEnsureData:
       
   887  * @key:		the pointer to key.
       
   888  * @dataId:		the requested data klass.
       
   889  * 
       
   890  * If necessary, creates key data of @dataId klass and adds to @key.
       
   891  *
       
   892  * Returns pointer to key data or NULL if an error occurs.
       
   893  */
       
   894 EXPORT_C
       
   895 xmlSecKeyDataPtr 
       
   896 xmlSecKeyEnsureData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
       
   897     xmlSecKeyDataPtr data;
       
   898     int ret;
       
   899         
       
   900     xmlSecAssert2(key != NULL, NULL);
       
   901     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
       
   902 
       
   903     data = xmlSecKeyGetData(key, dataId);
       
   904     if(data != NULL) {
       
   905 	return(data);
       
   906     }
       
   907     
       
   908     data = xmlSecKeyDataCreate(dataId);
       
   909     if(data == NULL) {
       
   910 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   911 		    NULL,
       
   912 		    "xmlSecKeyDataCreate",
       
   913 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   914 		    "dataId=%s", 
       
   915 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
       
   916 	return(NULL);
       
   917     }
       
   918 	
       
   919     ret = xmlSecKeyAdoptData(key, data);
       
   920     if(ret < 0) {
       
   921 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   922 		    NULL,
       
   923 		    "xmlSecKeyAdoptData",
       
   924 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   925 		    "dataId=%s", 
       
   926 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
       
   927 	xmlSecKeyDataDestroy(data);
       
   928 	return(NULL);
       
   929     }
       
   930     
       
   931     return(data);
       
   932 }
       
   933 
       
   934 /**
       
   935  * xmlSecKeyAdoptData:
       
   936  * @key:		the pointer to key.
       
   937  * @data:		the pointer to key data.
       
   938  *
       
   939  * Adds @data to the @key. The @data object will be destroyed
       
   940  * by @key.
       
   941  *
       
   942  * Returns 0 on success or a negative value otherwise.
       
   943  */
       
   944 EXPORT_C
       
   945 int 
       
   946 xmlSecKeyAdoptData(xmlSecKeyPtr key, xmlSecKeyDataPtr data) {
       
   947     xmlSecKeyDataPtr tmp;
       
   948     xmlSecSize pos, size;
       
   949     
       
   950     xmlSecAssert2(key != NULL, -1);
       
   951     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
       
   952 
       
   953     /* special cases */
       
   954     if(data->id == xmlSecKeyDataValueId) {
       
   955 	if(key->value != NULL) {
       
   956 	    xmlSecKeyDataDestroy(key->value);
       
   957 	}
       
   958 	key->value = data;
       
   959 	return(0);
       
   960     }
       
   961     
       
   962     if(key->dataList == NULL) {
       
   963 	key->dataList = xmlSecPtrListCreate(xmlSecKeyDataListId);
       
   964 	if(key->dataList == NULL) {
       
   965 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   966 			NULL,
       
   967 			"xmlSecPtrListCreate",
       
   968 		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   969 			XMLSEC_ERRORS_NO_MESSAGE);
       
   970 	    return(-1);
       
   971 	}
       
   972     }
       
   973 
       
   974 	
       
   975     size = xmlSecPtrListGetSize(key->dataList);
       
   976     for(pos = 0; pos < size; ++pos) {
       
   977 	tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
       
   978 	if((tmp != NULL) && (tmp->id == data->id)) {	
       
   979 	    return(xmlSecPtrListSet(key->dataList, data, pos));
       
   980 	}
       
   981     }
       
   982     
       
   983     return(xmlSecPtrListAdd(key->dataList, data));
       
   984 }
       
   985 
       
   986 /** 
       
   987  * xmlSecKeyDebugDump:
       
   988  * @key:		the pointer to key.
       
   989  * @output: 		the pointer to output FILE.
       
   990  *
       
   991  * Prints the information about the @key to the @output.
       
   992  */
       
   993 EXPORT_C
       
   994 void
       
   995 xmlSecKeyDebugDump(xmlSecKeyPtr key, FILE *output) {
       
   996     xmlSecAssert(xmlSecKeyIsValid(key));
       
   997     xmlSecAssert(output != NULL);
       
   998     
       
   999     fprintf(output, "== KEY\n");
       
  1000     fprintf(output, "=== method: %s\n", 
       
  1001 	    (key->value->id->dataNodeName != NULL) ? 
       
  1002 	    (char*)(key->value->id->dataNodeName) : "NULL"); 
       
  1003 
       
  1004     fprintf(output, "=== key type: ");
       
  1005     if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
       
  1006 	fprintf(output, "Symmetric\n");
       
  1007     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
       
  1008 	fprintf(output, "Private\n");
       
  1009     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
       
  1010 	fprintf(output, "Public\n");
       
  1011     } else {
       
  1012 	fprintf(output, "Unknown\n");
       
  1013     } 
       
  1014 
       
  1015     if(key->name != NULL) {
       
  1016 	fprintf(output, "=== key name: %s\n", key->name);
       
  1017     }
       
  1018     fprintf(output, "=== key usage: %d\n", key->usage);
       
  1019     if(key->notValidBefore < key->notValidAfter) {
       
  1020         fprintf(output, "=== key not valid before: %ld\n", (unsigned long)key->notValidBefore);
       
  1021 	fprintf(output, "=== key not valid after: %ld\n", (unsigned long)key->notValidAfter);
       
  1022     }
       
  1023     if(key->value != NULL) {
       
  1024 	xmlSecKeyDataDebugDump(key->value, output);
       
  1025     }
       
  1026     if(key->dataList != NULL) {
       
  1027 	xmlSecPtrListDebugDump(key->dataList, output);
       
  1028     }
       
  1029 }
       
  1030 
       
  1031 /** 
       
  1032  * xmlSecKeyDebugXmlDump:
       
  1033  * @key:		the pointer to key.
       
  1034  * @output: 		the pointer to output FILE.
       
  1035  *
       
  1036  * Prints the information about the @key to the @output in XML format.
       
  1037  */
       
  1038 EXPORT_C
       
  1039 void
       
  1040 xmlSecKeyDebugXmlDump(xmlSecKeyPtr key, FILE *output) {
       
  1041     xmlSecAssert(xmlSecKeyIsValid(key));
       
  1042     xmlSecAssert(output != NULL);
       
  1043     
       
  1044     fprintf(output, "<KeyInfo>\n");
       
  1045     if(key->value->id->dataNodeName != NULL) {
       
  1046         fprintf(output, "<KeyMethod>%s</KeyMethod>\n", 
       
  1047 		key->value->id->dataNodeName); 
       
  1048     }
       
  1049 
       
  1050     fprintf(output, "<KeyType>");
       
  1051     if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
       
  1052 	fprintf(output, "Symmetric\n");
       
  1053     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
       
  1054 	fprintf(output, "Private\n");
       
  1055     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
       
  1056 	fprintf(output, "Public\n");
       
  1057     } else {
       
  1058 	fprintf(output, "Unknown\n");
       
  1059     } 
       
  1060     fprintf(output, "</KeyType>\n");
       
  1061 
       
  1062     if(key->name != NULL) {
       
  1063 	fprintf(output, "<KeyName>%s</KeyName>\n", key->name);
       
  1064     }
       
  1065     if(key->notValidBefore < key->notValidAfter) {
       
  1066         fprintf(output, "<KeyValidity notValidBefore=\"%ld\" notValidAfter=\"%ld\"/>\n",
       
  1067 		(unsigned long)key->notValidBefore, 
       
  1068 		(unsigned long)key->notValidAfter);
       
  1069     }
       
  1070 
       
  1071     if(key->value != NULL) {
       
  1072 	xmlSecKeyDataDebugXmlDump(key->value, output);
       
  1073     }
       
  1074     if(key->dataList != NULL) {
       
  1075 	xmlSecPtrListDebugXmlDump(key->dataList, output);
       
  1076     }
       
  1077 
       
  1078     fprintf(output, "</KeyInfo>\n"); 
       
  1079 }
       
  1080 
       
  1081 /** 
       
  1082  * xmlSecKeyGenerate:
       
  1083  * @dataId:		the requested key klass (rsa, dsa, aes, ...).
       
  1084  * @sizeBits:		the new key size (in bits!).
       
  1085  * @type:		the new key type (session, permanent, ...).
       
  1086  *
       
  1087  * Generates new key of requested klass @dataId and @type.
       
  1088  *
       
  1089  * Returns pointer to newly created key or NULL if an error occurs.
       
  1090  */
       
  1091 EXPORT_C
       
  1092 xmlSecKeyPtr
       
  1093 xmlSecKeyGenerate(xmlSecKeyDataId dataId, xmlSecSize sizeBits, xmlSecKeyDataType type) {
       
  1094     xmlSecKeyPtr key;
       
  1095     xmlSecKeyDataPtr data;
       
  1096     int ret;
       
  1097 
       
  1098     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
       
  1099     
       
  1100     data = xmlSecKeyDataCreate(dataId);
       
  1101     if(data == NULL) {
       
  1102 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1103 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1104 		    "xmlSecKeyDataCreate",
       
  1105 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1106 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1107 	return(NULL);    
       
  1108     }
       
  1109 
       
  1110     ret = xmlSecKeyDataGenerate(data, sizeBits, type);
       
  1111     if(ret < 0) {
       
  1112 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1113 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1114 		    "xmlSecKeyDataGenerate",
       
  1115 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1116 		    "size=%d;type=%d", sizeBits, type);
       
  1117 	xmlSecKeyDataDestroy(data);
       
  1118 	return(NULL);    
       
  1119     }
       
  1120         
       
  1121     key = xmlSecKeyCreate();
       
  1122     if(key == NULL) {
       
  1123 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1124 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1125 		    "xmlSecKeyCreate",
       
  1126 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1127 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1128 	xmlSecKeyDataDestroy(data);
       
  1129 	return(NULL);    
       
  1130     }
       
  1131     
       
  1132     ret = xmlSecKeySetValue(key, data);
       
  1133     if(ret < 0) {
       
  1134 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1135 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1136 		    "xmlSecKeySetValue",
       
  1137 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1138 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1139 	xmlSecKeyDataDestroy(data);
       
  1140 	xmlSecKeyDestroy(key);
       
  1141 	return(NULL);    
       
  1142     }
       
  1143     
       
  1144     return(key);
       
  1145 }
       
  1146 
       
  1147 /** 
       
  1148  * xmlSecKeyGenerateByName:
       
  1149  * @name:		the requested key klass name (rsa, dsa, aes, ...).
       
  1150  * @sizeBits:		the new key size (in bits!).
       
  1151  * @type:		the new key type (session, permanent, ...).
       
  1152  *
       
  1153  * Generates new key of requested @klass and @type.
       
  1154  *
       
  1155  * Returns pointer to newly created key or NULL if an error occurs.
       
  1156  */
       
  1157 EXPORT_C
       
  1158 xmlSecKeyPtr
       
  1159 xmlSecKeyGenerateByName(const xmlChar* name, xmlSecSize sizeBits, xmlSecKeyDataType type) {
       
  1160     xmlSecKeyDataId dataId;
       
  1161 
       
  1162     xmlSecAssert2(name != NULL, NULL);
       
  1163     
       
  1164     dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), name, xmlSecKeyDataUsageAny);
       
  1165     if(dataId == xmlSecKeyDataIdUnknown) {
       
  1166 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1167 		    NULL,
       
  1168 		    xmlSecErrorsSafeString(name),
       
  1169 		    XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,
       
  1170 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1171 	return(NULL);    
       
  1172     }
       
  1173     
       
  1174     return(xmlSecKeyGenerate(dataId, sizeBits, type));
       
  1175 }
       
  1176 
       
  1177 /**
       
  1178  * xmlSecKeyReadBuffer:
       
  1179  * @dataId:		the key value data klass.
       
  1180  * @buffer:		the buffer that contains the binary data.
       
  1181  *
       
  1182  * Reads the key value of klass @dataId from a buffer.
       
  1183  *
       
  1184  * Returns pointer to newly created key or NULL if an error occurs.
       
  1185  */
       
  1186 EXPORT_C
       
  1187 xmlSecKeyPtr 
       
  1188 xmlSecKeyReadBuffer(xmlSecKeyDataId dataId, xmlSecBuffer* buffer) {
       
  1189     xmlSecKeyInfoCtx keyInfoCtx;
       
  1190     xmlSecKeyPtr key;
       
  1191     int ret;
       
  1192 
       
  1193     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
       
  1194     xmlSecAssert2(buffer != NULL, NULL);
       
  1195 
       
  1196     /* create key data */
       
  1197     key = xmlSecKeyCreate();
       
  1198     if(key == NULL) {
       
  1199 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1200 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1201 		    "xmlSecKeyCreate",
       
  1202 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1203 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1204 	return(NULL);    
       
  1205     }
       
  1206 
       
  1207     ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);    
       
  1208     if(ret < 0) {
       
  1209 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1210 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1211 		    "xmlSecKeyInfoCtxInitialize",
       
  1212 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1213 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1214 	xmlSecKeyDestroy(key);
       
  1215 	return(NULL);    
       
  1216     }
       
  1217     
       
  1218     keyInfoCtx.keyReq.keyType = xmlSecKeyDataTypeAny;
       
  1219     ret = xmlSecKeyDataBinRead(dataId, key, 
       
  1220 			xmlSecBufferGetData(buffer),
       
  1221 			xmlSecBufferGetSize(buffer),
       
  1222 			&keyInfoCtx);	
       
  1223     if(ret < 0) {
       
  1224 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1225 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1226 		    "xmlSecKeyDataBinRead",
       
  1227 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1228 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1229 	xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
       
  1230 	xmlSecKeyDestroy(key);
       
  1231 	return(NULL);    
       
  1232     }
       
  1233     xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
       
  1234     
       
  1235     return(key);
       
  1236 }
       
  1237 
       
  1238 /**
       
  1239  * xmlSecKeyReadBinaryFile:
       
  1240  * @dataId:		the key value data klass.
       
  1241  * @filename:		the key binary filename.
       
  1242  *
       
  1243  * Reads the key value of klass @dataId from a binary file @filename.
       
  1244  *
       
  1245  * Returns pointer to newly created key or NULL if an error occurs.
       
  1246  */
       
  1247 EXPORT_C
       
  1248 xmlSecKeyPtr 
       
  1249 xmlSecKeyReadBinaryFile(xmlSecKeyDataId dataId, const char* filename) {
       
  1250     xmlSecKeyPtr key;
       
  1251     xmlSecBuffer buffer;
       
  1252     int ret;
       
  1253     
       
  1254     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
       
  1255     xmlSecAssert2(filename != NULL, NULL);
       
  1256 
       
  1257     /* read file to buffer */
       
  1258     ret = xmlSecBufferInitialize(&buffer, 0);
       
  1259     if(ret < 0) {
       
  1260 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1261 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1262 		    "xmlSecBufferInitialize",
       
  1263 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1264 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1265 	return(NULL);	
       
  1266     }
       
  1267 
       
  1268     ret = xmlSecBufferReadFile(&buffer, filename);
       
  1269     if(ret < 0) {
       
  1270 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1271 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1272 		    "xmlSecBufferReadFile",
       
  1273 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1274 		    "filename=%s", 
       
  1275 		    xmlSecErrorsSafeString(filename));
       
  1276 	xmlSecBufferFinalize(&buffer);
       
  1277 	return(NULL);
       
  1278     }
       
  1279 
       
  1280     key = xmlSecKeyReadBuffer(dataId, &buffer);
       
  1281     if(key == NULL) {
       
  1282 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1283 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1284 		    "xmlSecKeyReadBuffer",
       
  1285 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1286 		    "filename=%s", 
       
  1287 		    xmlSecErrorsSafeString(filename));
       
  1288 	xmlSecBufferFinalize(&buffer);
       
  1289 	return(NULL);	
       
  1290     }
       
  1291 
       
  1292     xmlSecBufferFinalize(&buffer);
       
  1293     return (key);
       
  1294 }
       
  1295 
       
  1296 /**
       
  1297  * xmlSecKeyReadMemory:
       
  1298  * @dataId:		the key value data klass.
       
  1299  * @data:		the memory containing the key
       
  1300  * @dataSize: 		the size of the memory block
       
  1301  *
       
  1302  * Reads the key value of klass @dataId from a memory block @data.
       
  1303  *
       
  1304  * Returns pointer to newly created key or NULL if an error occurs.
       
  1305  */
       
  1306 EXPORT_C
       
  1307 xmlSecKeyPtr 
       
  1308 xmlSecKeyReadMemory(xmlSecKeyDataId dataId, const xmlSecByte* data, xmlSecSize dataSize) {
       
  1309     xmlSecBuffer buffer;
       
  1310     xmlSecKeyPtr key;
       
  1311     int ret;
       
  1312 
       
  1313     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
       
  1314     xmlSecAssert2(data != NULL, NULL);
       
  1315     xmlSecAssert2(dataSize > 0, NULL);
       
  1316 
       
  1317     /* read file to buffer */
       
  1318     ret = xmlSecBufferInitialize(&buffer, 0);
       
  1319     if(ret < 0) {
       
  1320 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1321 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1322 		    "xmlSecBufferInitialize",
       
  1323 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1324 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1325 	return(NULL);	
       
  1326     }
       
  1327 
       
  1328     if (xmlSecBufferAppend(&buffer, data, dataSize) < 0) {
       
  1329 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1330 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1331 		    "xmlSecBufferAppend",
       
  1332 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1333 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1334 	xmlSecBufferFinalize(&buffer);
       
  1335 	return(NULL);	
       
  1336     }
       
  1337 
       
  1338     key = xmlSecKeyReadBuffer(dataId, &buffer);
       
  1339     if(key == NULL) {
       
  1340 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1341 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
       
  1342 		    "xmlSecKeyReadBuffer",
       
  1343 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1344 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1345 	xmlSecBufferFinalize(&buffer);
       
  1346 	return(NULL);	
       
  1347     }
       
  1348 
       
  1349     xmlSecBufferFinalize(&buffer);
       
  1350     return (key);
       
  1351 }
       
  1352 
       
  1353 /**
       
  1354  * xmlSecKeysMngrGetKey:
       
  1355  * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
       
  1356  * @keyInfoCtx: 	the pointer to <dsig:KeyInfo/> node processing context.	
       
  1357  * 
       
  1358  * Reads the <dsig:KeyInfo/> node @keyInfoNode and extracts the key.
       
  1359  *
       
  1360  * Returns the pointer to key or NULL if the key is not found or 
       
  1361  * an error occurs.
       
  1362  */
       
  1363 EXPORT_C
       
  1364 xmlSecKeyPtr 		
       
  1365 xmlSecKeysMngrGetKey(xmlNodePtr keyInfoNode, xmlSecKeyInfoCtxPtr keyInfoCtx) {
       
  1366     xmlSecKeyPtr key;
       
  1367     xmlSecKeyPtr tempkey;
       
  1368     int ret;
       
  1369     const xmlChar* keyname;
       
  1370     
       
  1371     xmlSecAssert2(keyInfoCtx != NULL, NULL);
       
  1372 
       
  1373     
       
  1374     /* first try to read data from <dsig:KeyInfo/> node */
       
  1375     key = xmlSecKeyCreate();
       
  1376     if(key == NULL) {
       
  1377 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1378 		    NULL,
       
  1379 		    "xmlSecKeyCreate",
       
  1380 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1381 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1382 	return(NULL);
       
  1383     }
       
  1384 
       
  1385     if(keyInfoNode != NULL) {
       
  1386 	ret = xmlSecKeyInfoNodeRead(keyInfoNode, key, keyInfoCtx);
       
  1387 	if(ret < 0) {
       
  1388 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1389 			NULL,
       
  1390 			"xmlSecKeyInfoNodeRead",
       
  1391 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1392 			"node=%s",
       
  1393 			xmlSecErrorsSafeString(xmlSecNodeGetName(keyInfoNode)));
       
  1394 	    xmlSecKeyDestroy(key);
       
  1395 	    return(NULL);
       
  1396 	}
       
  1397 
       
  1398 	if((xmlSecKeyGetValue(key) != NULL) &&
       
  1399            (xmlSecKeyMatch(key, NULL, &(keyInfoCtx->keyReq)) != 0)) {
       
  1400             return(key);
       
  1401         }
       
  1402     }	
       
  1403         tempkey=xmlSecKeyDuplicate(key);
       
  1404         if(tempkey == NULL) 
       
  1405             {
       
  1406 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1407 			NULL,
       
  1408 			"xmlSecKeysMngrFindKey",
       
  1409 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1410 			XMLSEC_ERRORS_NO_MESSAGE);
       
  1411 	    return(NULL);
       
  1412             }
       
  1413         keyname=xmlSecKeyGetName(tempkey);	
       
  1414     xmlSecKeyDestroy(key);
       
  1415     
       
  1416     /* if we have keys manager, try it */
       
  1417     if(keyInfoCtx->keysMngr != NULL) {
       
  1418 	key = xmlSecKeysMngrFindKey(keyInfoCtx->keysMngr, keyname /*NULL*/, keyInfoCtx);
       
  1419          xmlSecKeyDestroy(tempkey);
       
  1420         	if(key == NULL) {
       
  1421 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1422 			NULL,
       
  1423 			"xmlSecKeysMngrFindKey",
       
  1424 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1425 			XMLSEC_ERRORS_NO_MESSAGE);
       
  1426 	    return(NULL);
       
  1427 	}
       
  1428 	if(xmlSecKeyGetValue(key) != NULL) {
       
  1429 	    return(key);
       
  1430 	}
       
  1431 	xmlSecKeyDestroy(key);
       
  1432     }
       
  1433     
       
  1434     xmlSecError(XMLSEC_ERRORS_HERE,
       
  1435 		NULL,
       
  1436 		NULL,
       
  1437 		XMLSEC_ERRORS_R_KEY_NOT_FOUND,
       
  1438 		XMLSEC_ERRORS_NO_MESSAGE);    
       
  1439     return(NULL);
       
  1440 }
       
  1441 
       
  1442 /***********************************************************************
       
  1443  *
       
  1444  * Keys list
       
  1445  *
       
  1446  **********************************************************************/
       
  1447 static xmlSecPtrListKlass xmlSecKeyPtrListKlass = {
       
  1448     BAD_CAST "keys-list",
       
  1449     (xmlSecPtrDuplicateItemMethod)xmlSecKeyDuplicate, 	/* xmlSecPtrDuplicateItemMethod duplicateItem; */
       
  1450     (xmlSecPtrDestroyItemMethod)xmlSecKeyDestroy,	/* xmlSecPtrDestroyItemMethod destroyItem; */
       
  1451     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugDump,	/* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
       
  1452     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugXmlDump,/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
       
  1453 };
       
  1454 
       
  1455 /**
       
  1456  * xmlSecKeyPtrListGetKlass: 
       
  1457  *
       
  1458  * The keys list klass.
       
  1459  *
       
  1460  * Returns keys list id.
       
  1461  */
       
  1462 EXPORT_C
       
  1463 xmlSecPtrListId 
       
  1464 xmlSecKeyPtrListGetKlass(void) {
       
  1465     return(&xmlSecKeyPtrListKlass);
       
  1466 }
       
  1467