|         |      1 /**  | 
|         |      2  * XMLSec library | 
|         |      3  * | 
|         |      4  * This is free software; see Copyright file in the source | 
|         |      5  * distribution for preciese wording. | 
|         |      6  *  | 
|         |      7  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> | 
|         |      8  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.  | 
|         |      9  */ | 
|         |     10 #include "xmlsecc_globals.h" | 
|         |     11  | 
|         |     12 #include <string.h> | 
|         |     13 #include "xmlsecc_config.h" | 
|         |     14 #include "xmlsec_xmlsec.h" | 
|         |     15 #include "xmlsec_xmltree.h" | 
|         |     16 #include "xmlsec_keys.h" | 
|         |     17 #include "xmlsec_keyinfo.h" | 
|         |     18 #include "xmlsec_transforms.h" | 
|         |     19 #include "xmlsec_errors.h" | 
|         |     20 #include "xmlsec_error_flag.h" | 
|         |     21  | 
|         |     22 #include "xmlsecc_crypto.h" | 
|         |     23 #include "xmlsecc_cryptowrapper.h" | 
|         |     24 #include "xmlsecc_evp.h" | 
|         |     25  | 
|         |     26 /************************************************************************** | 
|         |     27  * | 
|         |     28  * Internal SymbianCrypto EVP key CTX | 
|         |     29  * | 
|         |     30  *************************************************************************/ | 
|         |     31 typedef struct _xmlSecSymbianCryptoEvpKeyDataCtx	xmlSecSymbianCryptoEvpKeyDataCtx,  | 
|         |     32 						*xmlSecSymbianCryptoEvpKeyDataCtxPtr; | 
|         |     33 struct _xmlSecSymbianCryptoEvpKeyDataCtx { | 
|         |     34     EVP_PKEY*		pKey; | 
|         |     35 }; | 
|         |     36 	     | 
|         |     37 /****************************************************************************** | 
|         |     38  * | 
|         |     39  * EVP key (dsa/rsa) | 
|         |     40  * | 
|         |     41  * xmlSecSymbianCryptoEvpKeyDataCtx is located after xmlSecTransform | 
|         |     42  * | 
|         |     43  *****************************************************************************/ | 
|         |     44 #define xmlSecSymbianCryptoEvpKeyDataSize	\ | 
|         |     45     (sizeof(xmlSecKeyData) + sizeof(xmlSecSymbianCryptoEvpKeyDataCtx))	 | 
|         |     46 #define xmlSecSymbianCryptoEvpKeyDataGetCtx(data) \ | 
|         |     47     ((xmlSecSymbianCryptoEvpKeyDataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData))) | 
|         |     48  | 
|         |     49 static int		xmlSecSymbianCryptoEvpKeyDataInitialize	(xmlSecKeyDataPtr data); | 
|         |     50 static int		xmlSecSymbianCryptoEvpKeyDataDuplicate	(xmlSecKeyDataPtr dst, | 
|         |     51 								 xmlSecKeyDataPtr src); | 
|         |     52 static void		xmlSecSymbianCryptoEvpKeyDataFinalize		(xmlSecKeyDataPtr data); | 
|         |     53  | 
|         |     54 /** | 
|         |     55  * xmlSecSymbianCryptoEvpKeyDataAdoptEvp: | 
|         |     56  * @data:		the pointer to SymbianCrypto EVP key data. | 
|         |     57  * @pKey:		the pointer to EVP key. | 
|         |     58  * | 
|         |     59  * Sets the value of key data. | 
|         |     60  * | 
|         |     61  * Returns 0 on success or a negative value otherwise. | 
|         |     62  */ | 
|         |     63 EXPORT_C | 
|         |     64 int  | 
|         |     65 xmlSecSymbianCryptoEvpKeyDataAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) { | 
|         |     66     xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; | 
|         |     67  | 
|         |     68     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); | 
|         |     69     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize), -1); | 
|         |     70     xmlSecAssert2(pKey, -1); | 
|         |     71      | 
|         |     72     ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); | 
|         |     73     xmlSecAssert2(ctx, -1); | 
|         |     74      | 
|         |     75     if(ctx->pKey) { | 
|         |     76 	sc_pkey_free(ctx->pKey); | 
|         |     77     } | 
|         |     78     ctx->pKey = pKey; | 
|         |     79     return(0); | 
|         |     80 } | 
|         |     81  | 
|         |     82 /** | 
|         |     83  * xmlSecSymbianCryptoEvpKeyDataGetEvp: | 
|         |     84  * @data:		the pointer to SymbianCrypto EVP data. | 
|         |     85  * | 
|         |     86  * Gets the EVP_PKEY from the key data. | 
|         |     87  * | 
|         |     88  * Returns pointer to EVP_PKEY or NULL if an error occurs. | 
|         |     89  */ | 
|         |     90 EXPORT_C | 
|         |     91 EVP_PKEY*  | 
|         |     92 xmlSecSymbianCryptoEvpKeyDataGetEvp(xmlSecKeyDataPtr data) { | 
|         |     93     xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; | 
|         |     94  | 
|         |     95     xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL); | 
|         |     96     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize), NULL); | 
|         |     97  | 
|         |     98     ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); | 
|         |     99     xmlSecAssert2(ctx, NULL); | 
|         |    100  | 
|         |    101     return(ctx->pKey); | 
|         |    102  | 
|         |    103 	return NULL;     | 
|         |    104 } | 
|         |    105  | 
|         |    106 static int | 
|         |    107 xmlSecSymbianCryptoEvpKeyDataInitialize(xmlSecKeyDataPtr data) { | 
|         |    108     xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; | 
|         |    109  | 
|         |    110     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); | 
|         |    111     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize), -1); | 
|         |    112  | 
|         |    113     ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); | 
|         |    114     xmlSecAssert2(ctx, -1); | 
|         |    115  | 
|         |    116     memset(ctx, 0, sizeof(xmlSecSymbianCryptoEvpKeyDataCtx)); | 
|         |    117  | 
|         |    118     return(0); | 
|         |    119 } | 
|         |    120  | 
|         |    121 static int | 
|         |    122 xmlSecSymbianCryptoEvpKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { | 
|         |    123     xmlSecSymbianCryptoEvpKeyDataCtxPtr ctxDst; | 
|         |    124     xmlSecSymbianCryptoEvpKeyDataCtxPtr ctxSrc; | 
|         |    125  | 
|         |    126     xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1); | 
|         |    127     xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecSymbianCryptoEvpKeyDataSize), -1); | 
|         |    128     xmlSecAssert2(xmlSecKeyDataIsValid(src), -1); | 
|         |    129     xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecSymbianCryptoEvpKeyDataSize), -1); | 
|         |    130  | 
|         |    131     ctxDst = xmlSecSymbianCryptoEvpKeyDataGetCtx(dst); | 
|         |    132     xmlSecAssert2(ctxDst, -1); | 
|         |    133     xmlSecAssert2(!ctxDst->pKey, -1); | 
|         |    134  | 
|         |    135     ctxSrc = xmlSecSymbianCryptoEvpKeyDataGetCtx(src); | 
|         |    136     xmlSecAssert2(ctxSrc, -1); | 
|         |    137  | 
|         |    138     if(ctxSrc->pKey) { | 
|         |    139 	ctxDst->pKey = xmlSecSymbianCryptoEvpKeyDup(ctxSrc->pKey); | 
|         |    140             ctxDst->pKey->duplicate=0; | 
|         |    141             ctxSrc->pKey->duplicate=1; | 
|         |    142 	if(!ctxDst->pKey) { | 
|         |    143 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    144 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)), | 
|         |    145 			"xmlSecSymbianCryptoEvpKeyDup", | 
|         |    146 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    147 			XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    148 	    return(-1); | 
|         |    149 	}	 | 
|         |    150     }  | 
|         |    151  | 
|         |    152     return(0); | 
|         |    153 } | 
|         |    154  | 
|         |    155 static void | 
|         |    156 xmlSecSymbianCryptoEvpKeyDataFinalize(xmlSecKeyDataPtr data) { | 
|         |    157     xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; | 
|         |    158      | 
|         |    159     xmlSecAssert(xmlSecKeyDataIsValid(data)); | 
|         |    160     xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize)); | 
|         |    161  | 
|         |    162     ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); | 
|         |    163     xmlSecAssert(ctx); | 
|         |    164      | 
|         |    165     if(ctx->pKey) { | 
|         |    166 	sc_pkey_free(ctx->pKey); | 
|         |    167     } | 
|         |    168     memset(ctx, 0, sizeof(xmlSecSymbianCryptoEvpKeyDataCtx)); | 
|         |    169      | 
|         |    170 } | 
|         |    171 /**************************************************************************** | 
|         |    172  * | 
|         |    173  * Symbian Keys Store | 
|         |    174  * | 
|         |    175  ***************************************************************************/ | 
|         |    176 #define xmlSecSymbianKeysStoreSize \ | 
|         |    177 	(sizeof(xmlSecKeyStore)+ sizeof(xmlSecPtrList)) | 
|         |    178 #define xmlSecSymbianKeysStoreGetList(store) \ | 
|         |    179     ((xmlSecKeyStoreCheckSize((store), xmlSecSymbianKeysStoreSize)) ? \ | 
|         |    180 	(xmlSecPtrListPtr)(((xmlSecByte*)(store)) + sizeof(xmlSecKeyStore)) : \ | 
|         |    181 	(xmlSecPtrListPtr)NULL) | 
|         |    182  | 
|         |    183  | 
|         |    184 static xmlSecKeyPtr 		xmlSecSymbianKeysStoreFindKey	(xmlSecKeyStorePtr store,  | 
|         |    185 								 const xmlChar* name,  | 
|         |    186 								 xmlSecKeyInfoCtxPtr keyInfoCtx); | 
|         |    187  | 
|         |    188 static xmlSecKeyStoreKlass xmlSecSymbianKeysStoreKlass = { | 
|         |    189     sizeof(xmlSecKeyStoreKlass), | 
|         |    190     xmlSecSymbianKeysStoreSize, | 
|         |    191  | 
|         |    192     /* data */ | 
|         |    193     BAD_CAST "symbian-keys-store",		/* const xmlChar* name; */  | 
|         |    194          | 
|         |    195     /* constructors/destructor */ | 
|         |    196     NULL,		/* xmlSecKeyStoreInitializeMethod initialize; */ | 
|         |    197     NULL,		/* xmlSecKeyStoreFinalizeMethod finalize; */ | 
|         |    198     xmlSecSymbianKeysStoreFindKey,		/* xmlSecKeyStoreFindKeyMethod findKey; */ | 
|         |    199  | 
|         |    200     /* reserved for the future */ | 
|         |    201     NULL,					/* void* reserved0; */ | 
|         |    202     NULL, 					/* void* reserved1; */ | 
|         |    203 }; | 
|         |    204  | 
|         |    205 /** | 
|         |    206  * xmlSecSymbianKeysStoreGetKlass: | 
|         |    207  *  | 
|         |    208  * The Symbian list based keys store klass. | 
|         |    209  * | 
|         |    210  * Returns simple list based keys store klass. | 
|         |    211  */ | 
|         |    212 EXPORT_C | 
|         |    213 xmlSecKeyStoreId  | 
|         |    214 xmlSecSymbianKeysStoreGetKlass(void) { | 
|         |    215     return(&xmlSecSymbianKeysStoreKlass); | 
|         |    216 } | 
|         |    217  | 
|         |    218  | 
|         |    219 static xmlSecKeyPtr  | 
|         |    220 xmlSecSymbianKeysStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name,  | 
|         |    221 			    xmlSecKeyInfoCtxPtr keyInfoCtx) { | 
|         |    222    | 
|         |    223     xmlSecKeyPtr key=NULL; | 
|         |    224     | 
|         |    225     xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSymbianKeysStoreId), NULL); | 
|         |    226     xmlSecAssert2(keyInfoCtx, NULL); | 
|         |    227  | 
|         |    228     if((!name) || (keyInfoCtx->keyReq.keyId == xmlSecKeyDataIdUnknown)){ | 
|         |    229 	return(NULL); | 
|         |    230     } | 
|         |    231     if(keyInfoCtx->keyReq.keyId== xmlSecSymbianCryptoKeyDataRsaId) { | 
|         |    232  | 
|         |    233     key=xmlSecSymbianCryptoAppKeyLoadSks((char*)name);	 | 
|         |    234     if(!key) { | 
|         |    235             xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    236 		    NULL, | 
|         |    237 		    "xmlSecSymbianKeysStoreFindKey", | 
|         |    238 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    239 		    "name=%s",  | 
|         |    240 		    xmlSecErrorsSafeString(name)); | 
|         |    241 	    return(NULL); | 
|         |    242         } | 
|         |    243      | 
|         |    244     } | 
|         |    245     return(key); | 
|         |    246 } | 
|         |    247 /** | 
|         |    248  * xmlSecSymbianCryptoAppKeyLoadSks: | 
|         |    249  * @keyname:		the key name. | 
|         |    250  * | 
|         |    251  * Reads key from the symbian keystore. | 
|         |    252  * | 
|         |    253  * Returns pointer to the key or NULL if an error occurs. | 
|         |    254  */ | 
|         |    255 EXPORT_C | 
|         |    256 xmlSecKeyPtr | 
|         |    257 xmlSecSymbianCryptoAppKeyLoadSks(char* keyname) { | 
|         |    258  | 
|         |    259     xmlSecKeyPtr key = NULL; | 
|         |    260     xmlSecKeyDataPtr data; | 
|         |    261     EVP_PKEY* pKey = NULL;     | 
|         |    262  | 
|         |    263     int ret; | 
|         |    264  | 
|         |    265     xmlSecAssert2(keyname, NULL); | 
|         |    266  | 
|         |    267     pKey = d2i_PKCS8PrivateKey(keyname); | 
|         |    268     if(!pKey) { | 
|         |    269 		    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    270 				NULL, | 
|         |    271 				"sc_PrivateKey_read", | 
|         |    272 				XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |    273 				XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    274 		    return(NULL); | 
|         |    275 		}    					    		   | 
|         |    276      | 
|         |    277     data = xmlSecSymbianCryptoEvpKeyAdopt(pKey); | 
|         |    278     if(!data) { | 
|         |    279 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    280 		    NULL, | 
|         |    281 		    "xmlSecSymbianCryptoEvpKeyAdopt", | 
|         |    282 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    283 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    284 	sc_pkey_free(pKey); | 
|         |    285 	return(NULL);	     | 
|         |    286     }    | 
|         |    287       | 
|         |    288     key = xmlSecKeyCreate(); | 
|         |    289     if(!key) { | 
|         |    290 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    291 		    NULL, | 
|         |    292 		    "xmlSecKeyCreate", | 
|         |    293 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    294 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    295 	xmlSecKeyDataDestroy(data); | 
|         |    296 	return(NULL); | 
|         |    297     } | 
|         |    298      | 
|         |    299     ret = xmlSecKeySetValue(key, data); | 
|         |    300     if(ret < 0) { | 
|         |    301 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    302 		    NULL, | 
|         |    303 		    "xmlSecKeySetValue", | 
|         |    304 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    305 		    "data=%s", | 
|         |    306 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data))); | 
|         |    307 	xmlSecKeyDestroy(key); | 
|         |    308 	xmlSecKeyDataDestroy(data); | 
|         |    309 	return(NULL); | 
|         |    310     }  | 
|         |    311      | 
|         |    312     return(key); | 
|         |    313 } | 
|         |    314 /****************************************************************************** | 
|         |    315  * | 
|         |    316  * EVP helper functions | 
|         |    317  * | 
|         |    318  *****************************************************************************/ | 
|         |    319 /** | 
|         |    320  * xmlSecSymbianCryptoEvpKeyDup: | 
|         |    321  * @pKey:		the pointer to EVP_PKEY. | 
|         |    322  * | 
|         |    323  * Duplicates @pKey. | 
|         |    324  * | 
|         |    325  * Returns pointer to newly created EVP_PKEY object or NULL if an error occurs. | 
|         |    326  */ | 
|         |    327 EXPORT_C | 
|         |    328 EVP_PKEY*  | 
|         |    329 xmlSecSymbianCryptoEvpKeyDup(EVP_PKEY* pKey) { | 
|         |    330     int ret; | 
|         |    331     EVP_PKEY* pKeyNew; | 
|         |    332  | 
|         |    333     xmlSecAssert2(pKey, NULL); | 
|         |    334     | 
|         |    335     pKeyNew = sc_pkey_duplicate(pKey); | 
|         |    336     if(!pKeyNew) { | 
|         |    337 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    338 		    NULL, | 
|         |    339 		    "sc_pkey_duplicate", | 
|         |    340 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |    341 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    342 	return(NULL);		    	 | 
|         |    343     } | 
|         |    344  | 
|         |    345     return (pKeyNew); | 
|         |    346 } | 
|         |    347  | 
|         |    348 /** | 
|         |    349  * xmlSecSymbianCryptoEvpKeyAdopt: | 
|         |    350  * @pKey:		the pointer to EVP_PKEY. | 
|         |    351  * | 
|         |    352  * Creates xmlsec key object from SymbianCrypto key object. | 
|         |    353  * | 
|         |    354  * Returns pointer to newly created xmlsec key or NULL if an error occurs. | 
|         |    355  */ | 
|         |    356 EXPORT_C | 
|         |    357 xmlSecKeyDataPtr | 
|         |    358 xmlSecSymbianCryptoEvpKeyAdopt(EVP_PKEY *pKey) { | 
|         |    359     xmlSecKeyDataPtr data = NULL; | 
|         |    360     int ret; | 
|         |    361      | 
|         |    362     xmlSecAssert2(pKey, NULL); | 
|         |    363  | 
|         |    364     switch(pKey->type) {	 | 
|         |    365 #ifndef XMLSEC_NO_RSA     | 
|         |    366     case EVP_PKEY_RSA: | 
|         |    367 	data = xmlSecKeyDataCreate(xmlSecSymbianCryptoKeyDataRsaId); | 
|         |    368 	if(!data) { | 
|         |    369 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    370 			NULL, | 
|         |    371 			"xmlSecKeyDataCreate", | 
|         |    372 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    373 			"xmlSecSymbianCryptoKeyDataRsaId"); | 
|         |    374 	    return(NULL);	     | 
|         |    375 	} | 
|         |    376 	break; | 
|         |    377 #endif /* XMLSEC_NO_RSA */	 | 
|         |    378 #ifndef XMLSEC_NO_DSA	 | 
|         |    379     case EVP_PKEY_DSA: | 
|         |    380 	data = xmlSecKeyDataCreate(xmlSecSymbianCryptoKeyDataDsaId); | 
|         |    381 	if(!data) { | 
|         |    382 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    383 			NULL, | 
|         |    384 			"xmlSecKeyDataCreate", | 
|         |    385 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    386 			"xmlSecSymbianCryptoKeyDataDsaId"); | 
|         |    387 	    return(NULL);	     | 
|         |    388 	} | 
|         |    389 	break; | 
|         |    390 #endif /* XMLSEC_NO_DSA */	 | 
|         |    391     default:	 | 
|         |    392 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    393 		    NULL, | 
|         |    394 		    NULL, | 
|         |    395 		    XMLSEC_ERRORS_R_INVALID_TYPE, | 
|         |    396 		    "evp key type %d not supported", pKey->type); | 
|         |    397 	return(NULL); | 
|         |    398     } | 
|         |    399  | 
|         |    400     xmlSecAssert2(data, NULL);     | 
|         |    401     ret = xmlSecSymbianCryptoEvpKeyDataAdoptEvp(data, pKey); | 
|         |    402     if(ret < 0) {	 | 
|         |    403 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    404 		    NULL, | 
|         |    405 		    "xmlSecSymbianCryptoEvpKeyDataAdoptEvp", | 
|         |    406 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    407 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    408 	xmlSecKeyDataDestroy(data); | 
|         |    409 	return(NULL);	     | 
|         |    410     } | 
|         |    411     return(data); | 
|         |    412 } | 
|         |    413  | 
|         |    414 #ifndef XMLSEC_NO_DSA     | 
|         |    415 /************************************************************************** | 
|         |    416  * | 
|         |    417  * <dsig:DSAKeyValue> processing | 
|         |    418  * | 
|         |    419  * | 
|         |    420  * The DSAKeyValue Element (http://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue) | 
|         |    421  * | 
|         |    422  * DSA keys and the DSA signature algorithm are specified in [DSS].  | 
|         |    423  * DSA public key values can have the following fields: | 
|         |    424  *       | 
|         |    425  *   * P - a prime modulus meeting the [DSS] requirements  | 
|         |    426  *   * Q - an integer in the range 2**159 < Q < 2**160 which is a prime  | 
|         |    427  *         divisor of P-1  | 
|         |    428  *   * G - an integer with certain properties with respect to P and Q  | 
|         |    429  *   * Y - G**X mod P (where X is part of the private key and not made  | 
|         |    430  *	   public)  | 
|         |    431  *   * J - (P - 1) / Q  | 
|         |    432  *   * seed - a DSA prime generation seed  | 
|         |    433  *   * pgenCounter - a DSA prime generation counter | 
|         |    434  * | 
|         |    435  * Parameter J is available for inclusion solely for efficiency as it is  | 
|         |    436  * calculatable from P and Q. Parameters seed and pgenCounter are used in the  | 
|         |    437  * DSA prime number generation algorithm specified in [DSS]. As such, they are  | 
|         |    438  * optional but must either both be present or both be absent. This prime  | 
|         |    439  * generation algorithm is designed to provide assurance that a weak prime is  | 
|         |    440  * not being used and it yields a P and Q value. Parameters P, Q, and G can be  | 
|         |    441  * public and common to a group of users. They might be known from application  | 
|         |    442  * context. As such, they are optional but P and Q must either both appear or  | 
|         |    443  * both be absent. If all of P, Q, seed, and pgenCounter are present,  | 
|         |    444  * implementations are not required to check if they are consistent and are  | 
|         |    445  * free to use either P and Q or seed and pgenCounter. All parameters are  | 
|         |    446  * encoded as base64 [MIME] values. | 
|         |    447  *      | 
|         |    448  * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are  | 
|         |    449  * represented in XML as octet strings as defined by the ds:CryptoBinary type. | 
|         |    450  *      | 
|         |    451  * Schema Definition: | 
|         |    452  *      | 
|         |    453  * <element name="DSAKeyValue" type="ds:DSAKeyValueType"/>  | 
|         |    454  * <complexType name="DSAKeyValueType">  | 
|         |    455  *   <sequence> | 
|         |    456  *     <sequence minOccurs="0"> | 
|         |    457  *        <element name="P" type="ds:CryptoBinary"/>  | 
|         |    458  *        <element name="Q" type="ds:CryptoBinary"/> | 
|         |    459  *     </sequence> | 
|         |    460  *     <element name="G" type="ds:CryptoBinary" minOccurs="0"/>  | 
|         |    461  *     <element name="Y" type="ds:CryptoBinary"/>  | 
|         |    462  *     <element name="J" type="ds:CryptoBinary" minOccurs="0"/> | 
|         |    463  *     <sequence minOccurs="0"> | 
|         |    464  *       <element name="Seed" type="ds:CryptoBinary"/>  | 
|         |    465  *       <element name="PgenCounter" type="ds:CryptoBinary"/>  | 
|         |    466  *     </sequence> | 
|         |    467  *   </sequence> | 
|         |    468  * </complexType> | 
|         |    469  *      | 
|         |    470  * DTD Definition: | 
|         |    471  *      | 
|         |    472  *  <!ELEMENT DSAKeyValue ((P, Q)?, G?, Y, J?, (Seed, PgenCounter)?) >  | 
|         |    473  *  <!ELEMENT P (#PCDATA) > | 
|         |    474  *  <!ELEMENT Q (#PCDATA) > | 
|         |    475  *  <!ELEMENT G (#PCDATA) > | 
|         |    476  *  <!ELEMENT Y (#PCDATA) > | 
|         |    477  *  <!ELEMENT J (#PCDATA) > | 
|         |    478  *  <!ELEMENT Seed (#PCDATA) > | 
|         |    479  *  <!ELEMENT PgenCounter (#PCDATA) > | 
|         |    480  * | 
|         |    481  * ============================================================================ | 
|         |    482  *  | 
|         |    483  * To support reading/writing private keys an X element added (before Y). | 
|         |    484  * Note: The current implementation does not support Seed and PgenCounter! | 
|         |    485  * by this the P, Q and G are *required*! | 
|         |    486  * | 
|         |    487  *************************************************************************/ | 
|         |    488 static int		xmlSecSymbianCryptoKeyDataDsaInitialize	(xmlSecKeyDataPtr data); | 
|         |    489 static int		xmlSecSymbianCryptoKeyDataDsaDuplicate	(xmlSecKeyDataPtr dst, | 
|         |    490 								 xmlSecKeyDataPtr src); | 
|         |    491 static void		xmlSecSymbianCryptoKeyDataDsaFinalize		(xmlSecKeyDataPtr data); | 
|         |    492 static int		xmlSecSymbianCryptoKeyDataDsaXmlRead		(xmlSecKeyDataId id, | 
|         |    493 								 xmlSecKeyPtr key, | 
|         |    494 								 xmlNodePtr node, | 
|         |    495 								 xmlSecKeyInfoCtxPtr keyInfoCtx); | 
|         |    496 static int		xmlSecSymbianCryptoKeyDataDsaXmlWrite		(xmlSecKeyDataId id, | 
|         |    497 								 xmlSecKeyPtr key, | 
|         |    498 								 xmlNodePtr node, | 
|         |    499 								 xmlSecKeyInfoCtxPtr keyInfoCtx); | 
|         |    500 static int		xmlSecSymbianCryptoKeyDataDsaGenerate		(xmlSecKeyDataPtr data, | 
|         |    501 								 xmlSecSize sizeBits, | 
|         |    502 								 xmlSecKeyDataType type); | 
|         |    503  | 
|         |    504 static xmlSecKeyDataType xmlSecSymbianCryptoKeyDataDsaGetType		(xmlSecKeyDataPtr data); | 
|         |    505 static xmlSecSize		xmlSecSymbianCryptoKeyDataDsaGetSize		(xmlSecKeyDataPtr data); | 
|         |    506 static void		xmlSecSymbianCryptoKeyDataDsaDebugDump	(xmlSecKeyDataPtr data, | 
|         |    507 								 FILE* output); | 
|         |    508 static void		xmlSecSymbianCryptoKeyDataDsaDebugXmlDump	(xmlSecKeyDataPtr data, | 
|         |    509 								 FILE* output); | 
|         |    510  | 
|         |    511 static xmlSecKeyDataKlass xmlSecSymbianCryptoKeyDataDsaKlass = { | 
|         |    512     sizeof(xmlSecKeyDataKlass), | 
|         |    513     xmlSecSymbianCryptoEvpKeyDataSize, | 
|         |    514  | 
|         |    515     /* data */ | 
|         |    516     xmlSecNameDSAKeyValue, | 
|         |    517     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,  | 
|         |    518 						/* xmlSecKeyDataUsage usage; */ | 
|         |    519     xmlSecHrefDSAKeyValue,			/* const xmlChar* href; */ | 
|         |    520     xmlSecNodeDSAKeyValue,			/* const xmlChar* dataNodeName; */ | 
|         |    521     xmlSecDSigNs,				/* const xmlChar* dataNodeNs; */ | 
|         |    522      | 
|         |    523     /* constructors/destructor */ | 
|         |    524     xmlSecSymbianCryptoKeyDataDsaInitialize,		/* xmlSecKeyDataInitializeMethod initialize; */ | 
|         |    525     xmlSecSymbianCryptoKeyDataDsaDuplicate,		/* xmlSecKeyDataDuplicateMethod duplicate; */ | 
|         |    526     xmlSecSymbianCryptoKeyDataDsaFinalize,		/* xmlSecKeyDataFinalizeMethod finalize; */ | 
|         |    527     xmlSecSymbianCryptoKeyDataDsaGenerate,		/* xmlSecKeyDataGenerateMethod generate; */ | 
|         |    528      | 
|         |    529     /* get info */ | 
|         |    530     xmlSecSymbianCryptoKeyDataDsaGetType, 		/* xmlSecKeyDataGetTypeMethod getType; */ | 
|         |    531     xmlSecSymbianCryptoKeyDataDsaGetSize,		/* xmlSecKeyDataGetSizeMethod getSize; */ | 
|         |    532     NULL,					/* xmlSecKeyDataGetIdentifier getIdentifier; */     | 
|         |    533  | 
|         |    534     /* read/write */ | 
|         |    535     xmlSecSymbianCryptoKeyDataDsaXmlRead,		/* xmlSecKeyDataXmlReadMethod xmlRead; */ | 
|         |    536     xmlSecSymbianCryptoKeyDataDsaXmlWrite,		/* xmlSecKeyDataXmlWriteMethod xmlWrite; */ | 
|         |    537     NULL,					/* xmlSecKeyDataBinReadMethod binRead; */ | 
|         |    538     NULL,					/* xmlSecKeyDataBinWriteMethod binWrite; */ | 
|         |    539  | 
|         |    540     /* debug */ | 
|         |    541     xmlSecSymbianCryptoKeyDataDsaDebugDump,		/* xmlSecKeyDataDebugDumpMethod debugDump; */ | 
|         |    542     xmlSecSymbianCryptoKeyDataDsaDebugXmlDump, 	/* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ | 
|         |    543  | 
|         |    544     /* reserved for the future */ | 
|         |    545     NULL,					/* void* reserved0; */ | 
|         |    546     NULL,					/* void* reserved1; */ | 
|         |    547 }; | 
|         |    548  | 
|         |    549 /** | 
|         |    550  * xmlSecSymbianCryptoKeyDataDsaGetKlass: | 
|         |    551  *  | 
|         |    552  * The DSA key data klass. | 
|         |    553  * | 
|         |    554  * Returns pointer to DSA key data klass. | 
|         |    555  */ | 
|         |    556 xmlSecKeyDataId  | 
|         |    557 xmlSecSymbianCryptoKeyDataDsaGetKlass(void) { | 
|         |    558     return(&xmlSecSymbianCryptoKeyDataDsaKlass); | 
|         |    559 } | 
|         |    560  | 
|         |    561 /** | 
|         |    562  * xmlSecSymbianCryptoKeyDataDsaAdoptDsa: | 
|         |    563  * @data:		the pointer to DSA key data. | 
|         |    564  * @dsa:		the pointer to SymbianCrypto DSA key. | 
|         |    565  * | 
|         |    566  * Sets the value of DSA key data. | 
|         |    567  * | 
|         |    568  * Returns 0 on success or a negative value otherwise. | 
|         |    569  */  | 
|         |    570 int | 
|         |    571 xmlSecSymbianCryptoKeyDataDsaAdoptDsa(xmlSecKeyDataPtr data, DSA* dsa) { | 
|         |    572     EVP_PKEY* pKey = NULL; | 
|         |    573     int ret; | 
|         |    574      | 
|         |    575     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); | 
|         |    576      | 
|         |    577     /* construct new EVP_PKEY */ | 
|         |    578     if(dsa) { | 
|         |    579 	pKey = EVP_PKEY_new(); | 
|         |    580 	if(!pKey) { | 
|         |    581 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    582 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |    583 			"EVP_PKEY_new", | 
|         |    584 			XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |    585 			XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    586 	    return(-1); | 
|         |    587 	} | 
|         |    588 	 | 
|         |    589 	ret = EVP_PKEY_assign_DSA(pKey, dsa); | 
|         |    590 	if(ret != 1) { | 
|         |    591 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    592 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |    593 			"EVP_PKEY_assign_DSA", | 
|         |    594 			XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |    595 			XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    596 	    return(-1); | 
|         |    597 	}	 | 
|         |    598     } | 
|         |    599      | 
|         |    600     ret = xmlSecSymbianCryptoKeyDataDsaAdoptEvp(data, pKey); | 
|         |    601     if(ret < 0) { | 
|         |    602 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    603 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |    604 		    "xmlSecSymbianCryptoKeyDataDsaAdoptEvp", | 
|         |    605 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    606 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    607 	if(pKey) { | 
|         |    608 	    EVP_PKEY_free(pKey); | 
|         |    609 	} | 
|         |    610 	return(-1); | 
|         |    611     } | 
|         |    612     return(0);     | 
|         |    613 } | 
|         |    614  | 
|         |    615 /** | 
|         |    616  * xmlSecSymbianCryptoKeyDataDsaGetDsa: | 
|         |    617  * @data:		the pointer to DSA key data. | 
|         |    618  * | 
|         |    619  * Gets the SymbianCrypto DSA key from DSA key data. | 
|         |    620  * | 
|         |    621  * Returns pointer to SymbianCrypto DSA key or NULL if an error occurs. | 
|         |    622  */ | 
|         |    623 DSA*  | 
|         |    624 xmlSecSymbianCryptoKeyDataDsaGetDsa(xmlSecKeyDataPtr data) { | 
|         |    625     EVP_PKEY* pKey; | 
|         |    626      | 
|         |    627     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), NULL); | 
|         |    628      | 
|         |    629     pKey = xmlSecSymbianCryptoKeyDataDsaGetEvp(data); | 
|         |    630     xmlSecAssert2((!pKey) || (pKey->type == EVP_PKEY_DSA), NULL); | 
|         |    631      | 
|         |    632     return((pKey) ? pKey->pkey.dsa : (DSA*)NULL); | 
|         |    633 } | 
|         |    634  | 
|         |    635 /**  | 
|         |    636  * xmlSecSymbianCryptoKeyDataDsaAdoptEvp: | 
|         |    637  * @data:		the pointer to DSA key data. | 
|         |    638  * @pKey:		the pointer to SymbianCrypto EVP key. | 
|         |    639  * | 
|         |    640  * Sets the DSA key data value to SymbianCrypto EVP key. | 
|         |    641  * | 
|         |    642  * Returns 0 on success or a negative value otherwise. | 
|         |    643  */ | 
|         |    644 int  | 
|         |    645 xmlSecSymbianCryptoKeyDataDsaAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) { | 
|         |    646     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); | 
|         |    647     xmlSecAssert2(pKey, -1); | 
|         |    648     xmlSecAssert2(pKey->type == EVP_PKEY_DSA, -1); | 
|         |    649      | 
|         |    650     return(xmlSecSymbianCryptoEvpKeyDataAdoptEvp(data, pKey)); | 
|         |    651 } | 
|         |    652  | 
|         |    653 /** | 
|         |    654  * xmlSecSymbianCryptoKeyDataDsaGetEvp: | 
|         |    655  * @data:		the pointer to DSA key data. | 
|         |    656  * | 
|         |    657  * Gets the SymbianCrypto EVP key from DSA key data. | 
|         |    658  * | 
|         |    659  * Returns pointer to SymbianCrypto EVP key or NULL if an error occurs. | 
|         |    660  */ | 
|         |    661 EVP_PKEY*  | 
|         |    662 xmlSecSymbianCryptoKeyDataDsaGetEvp(xmlSecKeyDataPtr data) { | 
|         |    663     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), NULL); | 
|         |    664  | 
|         |    665     return(xmlSecSymbianCryptoEvpKeyDataGetEvp(data)); | 
|         |    666 } | 
|         |    667  | 
|         |    668 static int | 
|         |    669 xmlSecSymbianCryptoKeyDataDsaInitialize(xmlSecKeyDataPtr data) { | 
|         |    670     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); | 
|         |    671  | 
|         |    672     return(xmlSecSymbianCryptoEvpKeyDataInitialize(data)); | 
|         |    673 } | 
|         |    674  | 
|         |    675 static int | 
|         |    676 xmlSecSymbianCryptoKeyDataDsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { | 
|         |    677     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecSymbianCryptoKeyDataDsaId), -1); | 
|         |    678     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecSymbianCryptoKeyDataDsaId), -1); | 
|         |    679  | 
|         |    680     return(xmlSecSymbianCryptoEvpKeyDataDuplicate(dst, src)); | 
|         |    681 } | 
|         |    682  | 
|         |    683 static void | 
|         |    684 xmlSecSymbianCryptoKeyDataDsaFinalize(xmlSecKeyDataPtr data) { | 
|         |    685     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId)); | 
|         |    686      | 
|         |    687     xmlSecSymbianCryptoEvpKeyDataFinalize(data); | 
|         |    688 } | 
|         |    689  | 
|         |    690 static int | 
|         |    691 xmlSecSymbianCryptoKeyDataDsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, | 
|         |    692 				    xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { | 
|         |    693     xmlSecKeyDataPtr data; | 
|         |    694     xmlNodePtr cur; | 
|         |    695     DSA *dsa; | 
|         |    696     int ret; | 
|         |    697  | 
|         |    698     xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataDsaId, -1); | 
|         |    699     xmlSecAssert2(key, -1); | 
|         |    700     xmlSecAssert2(node, -1); | 
|         |    701     xmlSecAssert2(keyInfoCtx, -1); | 
|         |    702  | 
|         |    703     if(xmlSecKeyGetValue(key)) { | 
|         |    704 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    705 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    706 		    NULL, | 
|         |    707 		    XMLSEC_ERRORS_R_INVALID_KEY_DATA, | 
|         |    708 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    709 	return(-1);	 | 
|         |    710     } | 
|         |    711  | 
|         |    712     dsa = DSA_new(); | 
|         |    713     if(!dsa) { | 
|         |    714 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    715 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    716 		    "DSA_new", | 
|         |    717 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |    718 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    719 	return(-1); | 
|         |    720     } | 
|         |    721      | 
|         |    722     cur = xmlSecGetNextElementNode(node->children); | 
|         |    723  | 
|         |    724     /* first is P node. It is REQUIRED because we do not support Seed and PgenCounter*/ | 
|         |    725     if((!cur) || (!xmlSecCheckNodeName(cur,  xmlSecNodeDSAP, xmlSecDSigNs))) { | 
|         |    726 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    727 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    728 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |    729 		    XMLSEC_ERRORS_R_INVALID_NODE, | 
|         |    730 		    "node=%s",  | 
|         |    731 		    xmlSecErrorsSafeString(xmlSecNodeDSAP)); | 
|         |    732 	DSA_free(dsa);	 | 
|         |    733 	return(-1); | 
|         |    734     } | 
|         |    735     if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->p))) { | 
|         |    736 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    737 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    738 		    "xmlSecSymbianCryptoNodeGetBNValue",		     | 
|         |    739 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    740 		    "node=%s",  | 
|         |    741 		    xmlSecErrorsSafeString(xmlSecNodeDSAP)); | 
|         |    742 	DSA_free(dsa); | 
|         |    743 	return(-1); | 
|         |    744     } | 
|         |    745     cur = xmlSecGetNextElementNode(cur->next); | 
|         |    746  | 
|         |    747     /* next is Q node. It is REQUIRED because we do not support Seed and PgenCounter*/ | 
|         |    748     if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAQ, xmlSecDSigNs))) { | 
|         |    749 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    750 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    751 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |    752 		    XMLSEC_ERRORS_R_INVALID_NODE, | 
|         |    753 		    "node=%s",  | 
|         |    754 		    xmlSecErrorsSafeString(xmlSecNodeDSAQ)); | 
|         |    755 	DSA_free(dsa); | 
|         |    756 	return(-1); | 
|         |    757     } | 
|         |    758     if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->q))) { | 
|         |    759 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    760 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    761 		    "xmlSecSymbianCryptoNodeGetBNValue", | 
|         |    762 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    763 		    "node=%s",  | 
|         |    764 		    xmlSecErrorsSafeString(xmlSecNodeDSAQ)); | 
|         |    765 	DSA_free(dsa); | 
|         |    766 	return(-1); | 
|         |    767     } | 
|         |    768     cur = xmlSecGetNextElementNode(cur->next); | 
|         |    769  | 
|         |    770     /* next is G node. It is REQUIRED because we do not support Seed and PgenCounter*/ | 
|         |    771     if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAG, xmlSecDSigNs))) { | 
|         |    772 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    773 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    774 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |    775 		    XMLSEC_ERRORS_R_INVALID_NODE, | 
|         |    776 		    "node=%s",  | 
|         |    777 		    xmlSecErrorsSafeString(xmlSecNodeDSAG)); | 
|         |    778 	DSA_free(dsa); | 
|         |    779 	return(-1); | 
|         |    780     } | 
|         |    781     if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->g))) { | 
|         |    782 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    783 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    784 		    "xmlSecSymbianCryptoNodeGetBNValue", | 
|         |    785 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    786 		    "node=%s",  | 
|         |    787 		    xmlSecErrorsSafeString(xmlSecNodeDSAG)); | 
|         |    788 	DSA_free(dsa); | 
|         |    789 	return(-1); | 
|         |    790     } | 
|         |    791     cur = xmlSecGetNextElementNode(cur->next); | 
|         |    792  | 
|         |    793     if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAX, xmlSecNs))) { | 
|         |    794         /* next is X node. It is REQUIRED for private key but | 
|         |    795 	 * we are not sure exactly what do we read */ | 
|         |    796 	if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->priv_key))) { | 
|         |    797 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    798 			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    799 			"xmlSecSymbianCryptoNodeGetBNValue", | 
|         |    800 		        XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    801 			"node=%s",  | 
|         |    802 			xmlSecErrorsSafeString(xmlSecNodeDSAX)); | 
|         |    803 	    DSA_free(dsa); | 
|         |    804 	    return(-1); | 
|         |    805 	} | 
|         |    806 	cur = xmlSecGetNextElementNode(cur->next); | 
|         |    807     } | 
|         |    808  | 
|         |    809     /* next is Y node. */ | 
|         |    810     if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAY, xmlSecDSigNs))) { | 
|         |    811 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    812 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    813 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |    814 		    XMLSEC_ERRORS_R_INVALID_NODE, | 
|         |    815 		    "node=%s",  | 
|         |    816 		    xmlSecErrorsSafeString(xmlSecNodeDSAY)); | 
|         |    817 	DSA_free(dsa); | 
|         |    818 	return(-1); | 
|         |    819     } | 
|         |    820     if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->pub_key))) { | 
|         |    821 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    822 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    823 		    "xmlSecSymbianCryptoNodeGetBNValue", | 
|         |    824 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    825 		    "node=%s", xmlSecErrorsSafeString(xmlSecNodeDSAY)); | 
|         |    826 	DSA_free(dsa); | 
|         |    827 	return(-1); | 
|         |    828     } | 
|         |    829     cur = xmlSecGetNextElementNode(cur->next); | 
|         |    830  | 
|         |    831     if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAJ, xmlSecDSigNs))) { | 
|         |    832 	cur = xmlSecGetNextElementNode(cur->next);   | 
|         |    833     } | 
|         |    834      | 
|         |    835     if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSASeed, xmlSecDSigNs))) { | 
|         |    836 	cur = xmlSecGetNextElementNode(cur->next);   | 
|         |    837     } | 
|         |    838  | 
|         |    839     if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAPgenCounter, xmlSecDSigNs))) { | 
|         |    840 	cur = xmlSecGetNextElementNode(cur->next);   | 
|         |    841     } | 
|         |    842  | 
|         |    843     if(cur) { | 
|         |    844 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    845 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    846 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |    847 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE, | 
|         |    848 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    849 	DSA_free(dsa); | 
|         |    850 	return(-1); | 
|         |    851     } | 
|         |    852  | 
|         |    853     data = xmlSecKeyDataCreate(id); | 
|         |    854     if(!data) { | 
|         |    855 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    856 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    857 		    "xmlSecKeyDataCreate", | 
|         |    858 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    859 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    860 	DSA_free(dsa); | 
|         |    861 	return(-1); | 
|         |    862     } | 
|         |    863  | 
|         |    864     ret = xmlSecSymbianCryptoKeyDataDsaAdoptDsa(data, dsa); | 
|         |    865     if(ret < 0) { | 
|         |    866 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    867 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |    868 		    "xmlSecSymbianCryptoKeyDataDsaAdoptDsa", | 
|         |    869 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    870 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    871 	xmlSecKeyDataDestroy(data); | 
|         |    872 	DSA_free(dsa); | 
|         |    873 	return(-1); | 
|         |    874     } | 
|         |    875  | 
|         |    876     ret = xmlSecKeySetValue(key, data); | 
|         |    877     if(ret < 0) { | 
|         |    878 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    879 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |    880 		    "xmlSecKeySetValue", | 
|         |    881 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    882 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |    883 	xmlSecKeyDataDestroy(data); | 
|         |    884 	return(-1);	 | 
|         |    885     } | 
|         |    886  | 
|         |    887     return(0); | 
|         |    888 } | 
|         |    889  | 
|         |    890 static int  | 
|         |    891 xmlSecSymbianCryptoKeyDataDsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, | 
|         |    892 				xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { | 
|         |    893     xmlNodePtr cur; | 
|         |    894     DSA* dsa; | 
|         |    895     int ret; | 
|         |    896      | 
|         |    897     xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataDsaId, -1); | 
|         |    898     xmlSecAssert2(key, -1); | 
|         |    899     xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key),  | 
|         |    900                                 xmlSecSymbianCryptoKeyDataDsaId), -1); | 
|         |    901     xmlSecAssert2(node, -1); | 
|         |    902     xmlSecAssert2(keyInfoCtx, -1); | 
|         |    903  | 
|         |    904     dsa = xmlSecSymbianCryptoKeyDataDsaGetDsa(xmlSecKeyGetValue(key)); | 
|         |    905     xmlSecAssert2(dsa, -1); | 
|         |    906      | 
|         |    907     if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) { | 
|         |    908 	/* we can have only private key or public key */ | 
|         |    909 	return(0); | 
|         |    910     }     | 
|         |    911      | 
|         |    912     /* first is P node */ | 
|         |    913     xmlSecAssert2(dsa->p, -1); | 
|         |    914     cur = xmlSecAddChild(node, xmlSecNodeDSAP, xmlSecDSigNs); | 
|         |    915     if(!cur) { | 
|         |    916 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    917 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    918 		    "xmlSecAddChild", | 
|         |    919 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    920 		    "node=%s",  | 
|         |    921 		    xmlSecErrorsSafeString(xmlSecNodeDSAP)); | 
|         |    922 	return(-1);	 | 
|         |    923     } | 
|         |    924     ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->p, 1); | 
|         |    925     if(ret < 0) { | 
|         |    926 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    927 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    928 		    "xmlSecSymbianCryptoNodeSetBNValue", | 
|         |    929 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    930 		    "node=%s",  | 
|         |    931 		    xmlSecErrorsSafeString(xmlSecNodeDSAP)); | 
|         |    932 	return(-1); | 
|         |    933     }     | 
|         |    934  | 
|         |    935     /* next is Q node. */ | 
|         |    936     xmlSecAssert2(dsa->q, -1); | 
|         |    937     cur = xmlSecAddChild(node, xmlSecNodeDSAQ, xmlSecDSigNs); | 
|         |    938     if(!cur) { | 
|         |    939 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    940 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    941 		    "xmlSecAddChild", | 
|         |    942 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    943 		    "node=%s",  | 
|         |    944 		    xmlSecErrorsSafeString(xmlSecNodeDSAQ)); | 
|         |    945 	return(-1);	 | 
|         |    946     } | 
|         |    947     ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->q, 1); | 
|         |    948     if(ret < 0) { | 
|         |    949 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    950 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    951 		    "xmlSecSymbianCryptoNodeSetBNValue", | 
|         |    952 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    953 		    "node=%s",  | 
|         |    954 		    xmlSecErrorsSafeString(xmlSecNodeDSAQ)); | 
|         |    955 	return(-1); | 
|         |    956     } | 
|         |    957  | 
|         |    958     /* next is G node. */ | 
|         |    959     xmlSecAssert2(dsa->g, -1); | 
|         |    960     cur = xmlSecAddChild(node, xmlSecNodeDSAG, xmlSecDSigNs); | 
|         |    961     if(!cur) { | 
|         |    962 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    963 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    964 		    "xmlSecAddChild", | 
|         |    965 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    966 		    "node=%s",  | 
|         |    967 		    xmlSecErrorsSafeString(xmlSecNodeDSAG)); | 
|         |    968 	return(-1);	 | 
|         |    969     } | 
|         |    970     ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->g, 1); | 
|         |    971     if(ret < 0) { | 
|         |    972 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    973 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    974 		    "xmlSecSymbianCryptoNodeSetBNValue", | 
|         |    975 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    976 		    "node=%s",  | 
|         |    977 		    xmlSecErrorsSafeString(xmlSecNodeDSAG)); | 
|         |    978 	return(-1); | 
|         |    979     } | 
|         |    980  | 
|         |    981     /* next is X node: write it ONLY for private keys and ONLY if it is requested */ | 
|         |    982     if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (dsa->priv_key)) { | 
|         |    983 	cur = xmlSecAddChild(node, xmlSecNodeDSAX, xmlSecNs); | 
|         |    984 	if(!cur) { | 
|         |    985 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    986 			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    987 			"xmlSecAddChild", | 
|         |    988 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    989 			"node=%s",  | 
|         |    990 			xmlSecErrorsSafeString(xmlSecNodeDSAX)); | 
|         |    991 	    return(-1);	 | 
|         |    992 	} | 
|         |    993 	ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->priv_key, 1); | 
|         |    994 	if(ret < 0) { | 
|         |    995 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |    996 			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |    997 			"xmlSecSymbianCryptoNodeSetBNValue", | 
|         |    998 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |    999 			"node=%s",  | 
|         |   1000 			xmlSecErrorsSafeString(xmlSecNodeDSAX)); | 
|         |   1001 	    return(-1); | 
|         |   1002 	} | 
|         |   1003     } | 
|         |   1004  | 
|         |   1005     /* next is Y node. */ | 
|         |   1006     xmlSecAssert2(dsa->pub_key, -1); | 
|         |   1007     cur = xmlSecAddChild(node, xmlSecNodeDSAY, xmlSecDSigNs); | 
|         |   1008     if(!cur) { | 
|         |   1009 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1010 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1011 		    "xmlSecAddChild", | 
|         |   1012 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1013 		    "node=%s",  | 
|         |   1014 		    xmlSecErrorsSafeString(xmlSecNodeDSAY)); | 
|         |   1015 	return(-1);	 | 
|         |   1016     } | 
|         |   1017     ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->pub_key, 1); | 
|         |   1018     if(ret < 0) { | 
|         |   1019 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1020 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1021 		    "xmlSecSymbianCryptoNodeSetBNValue", | 
|         |   1022 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1023 		    "node=%s",  | 
|         |   1024 		    xmlSecErrorsSafeString(xmlSecNodeDSAY)); | 
|         |   1025 	return(-1); | 
|         |   1026     } | 
|         |   1027     return(0); | 
|         |   1028 } | 
|         |   1029  | 
|         |   1030 static int | 
|         |   1031 xmlSecSymbianCryptoKeyDataDsaGenerate(xmlSecKeyDataPtr data,  | 
|         |   1032                             xmlSecSize sizeBits,  | 
|         |   1033                             xmlSecKeyDataType type ATTRIBUTE_UNUSED) { | 
|         |   1034     DSA* dsa; | 
|         |   1035     int counter_ret; | 
|         |   1036     unsigned long h_ret; | 
|         |   1037     int ret; | 
|         |   1038      | 
|         |   1039     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); | 
|         |   1040     xmlSecAssert2(sizeBits > 0, -1); | 
|         |   1041  | 
|         |   1042     dsa = DSA_generate_parameters(sizeBits, NULL, 0, &counter_ret, &h_ret, NULL, NULL);  | 
|         |   1043     if(!dsa) { | 
|         |   1044 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1045 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1046 		    "DSA_generate_parameters", | 
|         |   1047 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1048 		    "size=%d", sizeBits); | 
|         |   1049 	return(-1);     | 
|         |   1050     } | 
|         |   1051  | 
|         |   1052     ret = DSA_generate_key(dsa); | 
|         |   1053     if(ret < 0) { | 
|         |   1054 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1055 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1056 		    "DSA_generate_key", | 
|         |   1057 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1058 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1059 	DSA_free(dsa); | 
|         |   1060 	return(-1);     | 
|         |   1061     } | 
|         |   1062  | 
|         |   1063     ret = xmlSecSymbianCryptoKeyDataDsaAdoptDsa(data, dsa); | 
|         |   1064     if(ret < 0) { | 
|         |   1065 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1066 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1067 		    "xmlSecSymbianCryptoKeyDataDsaAdoptDsa", | 
|         |   1068 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1069 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1070 	DSA_free(dsa); | 
|         |   1071 	return(-1); | 
|         |   1072     } | 
|         |   1073  | 
|         |   1074     return(0); | 
|         |   1075 } | 
|         |   1076  | 
|         |   1077 static xmlSecKeyDataType | 
|         |   1078 xmlSecSymbianCryptoKeyDataDsaGetType(xmlSecKeyDataPtr data) { | 
|         |   1079     DSA* dsa; | 
|         |   1080      | 
|         |   1081     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId),  | 
|         |   1082                                 xmlSecKeyDataTypeUnknown); | 
|         |   1083      | 
|         |   1084     dsa = xmlSecSymbianCryptoKeyDataDsaGetDsa(data); | 
|         |   1085     if((dsa) && (dsa->p) && (dsa->q) &&  | 
|         |   1086        (dsa->g) && (dsa->pub_key)) { | 
|         |   1087         | 
|         |   1088         if(dsa->priv_key) { | 
|         |   1089 	    return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); | 
|         |   1090 	} else if(dsa->engine) { | 
|         |   1091 	    /** | 
|         |   1092 	     * | 
|         |   1093 	     * We assume here that engine *always* has private key. | 
|         |   1094 	     * This might be incorrect but it seems that there is no | 
|         |   1095 	     * way to ask engine if given key is private or not. | 
|         |   1096 	     */ | 
|         |   1097 	    return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); | 
|         |   1098 	} else { | 
|         |   1099 	    return(xmlSecKeyDataTypePublic); | 
|         |   1100 	} | 
|         |   1101     } | 
|         |   1102  | 
|         |   1103     return(xmlSecKeyDataTypeUnknown); | 
|         |   1104 } | 
|         |   1105  | 
|         |   1106 static xmlSecSize  | 
|         |   1107 xmlSecSymbianCryptoKeyDataDsaGetSize(xmlSecKeyDataPtr data) { | 
|         |   1108     DSA* dsa; | 
|         |   1109  | 
|         |   1110     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), 0); | 
|         |   1111  | 
|         |   1112     dsa = xmlSecSymbianCryptoKeyDataDsaGetDsa(data); | 
|         |   1113     if((dsa) && (dsa->p)) { | 
|         |   1114 	return(BN_num_bits(dsa->p)); | 
|         |   1115     }     | 
|         |   1116     return(0); | 
|         |   1117 } | 
|         |   1118  | 
|         |   1119 static void  | 
|         |   1120 xmlSecSymbianCryptoKeyDataDsaDebugDump(xmlSecKeyDataPtr data, FILE* output) { | 
|         |   1121     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId)); | 
|         |   1122     xmlSecAssert(output); | 
|         |   1123      | 
|         |   1124     fprintf(output, "=== dsa key: size = %d\n",  | 
|         |   1125 	    xmlSecSymbianCryptoKeyDataDsaGetSize(data)); | 
|         |   1126 } | 
|         |   1127  | 
|         |   1128 static void | 
|         |   1129 xmlSecSymbianCryptoKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { | 
|         |   1130     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId)); | 
|         |   1131     xmlSecAssert(output); | 
|         |   1132          | 
|         |   1133     fprintf(output, "<DSAKeyValue size=\"%d\" />\n",  | 
|         |   1134 	    xmlSecSymbianCryptoKeyDataDsaGetSize(data)); | 
|         |   1135 } | 
|         |   1136  | 
|         |   1137 #endif /* XMLSEC_NO_DSA */ | 
|         |   1138  | 
|         |   1139 #ifndef XMLSEC_NO_RSA | 
|         |   1140 /************************************************************************** | 
|         |   1141  * | 
|         |   1142  * <dsig:RSAKeyValue> processing | 
|         |   1143  * | 
|         |   1144  * http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue | 
|         |   1145  * The RSAKeyValue Element | 
|         |   1146  * | 
|         |   1147  * RSA key values have two fields: Modulus and Exponent. | 
|         |   1148  * | 
|         |   1149  * <RSAKeyValue> | 
|         |   1150  *   <Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W | 
|         |   1151  *     jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV | 
|         |   1152  *   	  5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U= | 
|         |   1153  *   </Modulus> | 
|         |   1154  *   <Exponent>AQAB</Exponent> | 
|         |   1155  * </RSAKeyValue> | 
|         |   1156  * | 
|         |   1157  * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are  | 
|         |   1158  * represented in XML as octet strings as defined by the ds:CryptoBinary type. | 
|         |   1159  * | 
|         |   1160  * Schema Definition: | 
|         |   1161  *  | 
|         |   1162  * <element name="RSAKeyValue" type="ds:RSAKeyValueType"/> | 
|         |   1163  * <complexType name="RSAKeyValueType"> | 
|         |   1164  *   <sequence> | 
|         |   1165  *     <element name="Modulus" type="ds:CryptoBinary"/>  | 
|         |   1166  *     <element name="Exponent" type="ds:CryptoBinary"/> | 
|         |   1167  *   </sequence> | 
|         |   1168  * </complexType> | 
|         |   1169  * | 
|         |   1170  * DTD Definition: | 
|         |   1171  *  | 
|         |   1172  * <!ELEMENT RSAKeyValue (Modulus, Exponent) >  | 
|         |   1173  * <!ELEMENT Modulus (#PCDATA) > | 
|         |   1174  * <!ELEMENT Exponent (#PCDATA) > | 
|         |   1175  * | 
|         |   1176  * ============================================================================ | 
|         |   1177  *  | 
|         |   1178  * To support reading/writing private keys an PrivateExponent element is added | 
|         |   1179  * to the end | 
|         |   1180  * | 
|         |   1181  *************************************************************************/ | 
|         |   1182  | 
|         |   1183 static int		xmlSecSymbianCryptoKeyDataRsaInitialize	(xmlSecKeyDataPtr data); | 
|         |   1184 static int		xmlSecSymbianCryptoKeyDataRsaDuplicate	(xmlSecKeyDataPtr dst, | 
|         |   1185 								 xmlSecKeyDataPtr src); | 
|         |   1186 static void		xmlSecSymbianCryptoKeyDataRsaFinalize		(xmlSecKeyDataPtr data); | 
|         |   1187 static int		xmlSecSymbianCryptoKeyDataRsaXmlRead		(xmlSecKeyDataId id, | 
|         |   1188 								 xmlSecKeyPtr key, | 
|         |   1189 								 xmlNodePtr node, | 
|         |   1190 								 xmlSecKeyInfoCtxPtr keyInfoCtx); | 
|         |   1191 static int		xmlSecSymbianCryptoKeyDataRsaXmlWrite		(xmlSecKeyDataId id, | 
|         |   1192 								 xmlSecKeyPtr key, | 
|         |   1193 								 xmlNodePtr node, | 
|         |   1194 								 xmlSecKeyInfoCtxPtr keyInfoCtx); | 
|         |   1195 static int		xmlSecSymbianCryptoKeyDataRsaGenerate		(xmlSecKeyDataPtr data, | 
|         |   1196 							    	 xmlSecSize sizeBits, | 
|         |   1197 								 xmlSecKeyDataType type); | 
|         |   1198  | 
|         |   1199 static xmlSecKeyDataType xmlSecSymbianCryptoKeyDataRsaGetType		(xmlSecKeyDataPtr data); | 
|         |   1200 static xmlSecSize		xmlSecSymbianCryptoKeyDataRsaGetSize		(xmlSecKeyDataPtr data); | 
|         |   1201 static void		xmlSecSymbianCryptoKeyDataRsaDebugDump	(xmlSecKeyDataPtr data, | 
|         |   1202 								 FILE* output); | 
|         |   1203 static void		xmlSecSymbianCryptoKeyDataRsaDebugXmlDump	(xmlSecKeyDataPtr data, | 
|         |   1204 								 FILE* output); | 
|         |   1205 static xmlSecKeyDataKlass xmlSecSymbianCryptoKeyDataRsaKlass = { | 
|         |   1206     sizeof(xmlSecKeyDataKlass), | 
|         |   1207     xmlSecSymbianCryptoEvpKeyDataSize, | 
|         |   1208  | 
|         |   1209     /* data */ | 
|         |   1210     xmlSecNameRSAKeyValue, | 
|         |   1211     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,  | 
|         |   1212 						/* xmlSecKeyDataUsage usage; */ | 
|         |   1213     xmlSecHrefRSAKeyValue,			/* const xmlChar* href; */ | 
|         |   1214     xmlSecNodeRSAKeyValue,			/* const xmlChar* dataNodeName; */ | 
|         |   1215     xmlSecDSigNs,				/* const xmlChar* dataNodeNs; */ | 
|         |   1216      | 
|         |   1217     /* constructors/destructor */ | 
|         |   1218     xmlSecSymbianCryptoKeyDataRsaInitialize,		/* xmlSecKeyDataInitializeMethod initialize; */ | 
|         |   1219     xmlSecSymbianCryptoKeyDataRsaDuplicate,		/* xmlSecKeyDataDuplicateMethod duplicate; */ | 
|         |   1220     xmlSecSymbianCryptoKeyDataRsaFinalize,		/* xmlSecKeyDataFinalizeMethod finalize; */ | 
|         |   1221     xmlSecSymbianCryptoKeyDataRsaGenerate,		/* xmlSecKeyDataGenerateMethod generate; */ | 
|         |   1222      | 
|         |   1223     /* get info */ | 
|         |   1224     xmlSecSymbianCryptoKeyDataRsaGetType, 		/* xmlSecKeyDataGetTypeMethod getType; */ | 
|         |   1225     xmlSecSymbianCryptoKeyDataRsaGetSize,		/* xmlSecKeyDataGetSizeMethod getSize; */ | 
|         |   1226     NULL,					/* xmlSecKeyDataGetIdentifier getIdentifier; */     | 
|         |   1227  | 
|         |   1228     /* read/write */ | 
|         |   1229     xmlSecSymbianCryptoKeyDataRsaXmlRead,		/* xmlSecKeyDataXmlReadMethod xmlRead; */ | 
|         |   1230     xmlSecSymbianCryptoKeyDataRsaXmlWrite,		/* xmlSecKeyDataXmlWriteMethod xmlWrite; */ | 
|         |   1231     NULL,					/* xmlSecKeyDataBinReadMethod binRead; */ | 
|         |   1232     NULL,					/* xmlSecKeyDataBinWriteMethod binWrite; */ | 
|         |   1233  | 
|         |   1234     /* debug */ | 
|         |   1235     xmlSecSymbianCryptoKeyDataRsaDebugDump,		/* xmlSecKeyDataDebugDumpMethod debugDump; */ | 
|         |   1236     xmlSecSymbianCryptoKeyDataRsaDebugXmlDump, 	/* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ | 
|         |   1237  | 
|         |   1238     /* reserved for the future */ | 
|         |   1239     NULL,					/* void* reserved0; */ | 
|         |   1240     NULL,					/* void* reserved1; */ | 
|         |   1241 }; | 
|         |   1242  | 
|         |   1243 /**  | 
|         |   1244  * xmlSecSymbianCryptoKeyDataRsaGetKlass: | 
|         |   1245  * | 
|         |   1246  * The SymbianCrypto RSA key data klass. | 
|         |   1247  * | 
|         |   1248  * Returns pointer to SymbianCrypto RSA key data klass. | 
|         |   1249  */ | 
|         |   1250 EXPORT_C | 
|         |   1251 xmlSecKeyDataId  | 
|         |   1252 xmlSecSymbianCryptoKeyDataRsaGetKlass(void) { | 
|         |   1253     return(&xmlSecSymbianCryptoKeyDataRsaKlass); | 
|         |   1254 } | 
|         |   1255  | 
|         |   1256 /** | 
|         |   1257  * xmlSecSymbianCryptoKeyDataRsaAdoptRsa: | 
|         |   1258  * @data:		the pointer to RSA key data. | 
|         |   1259  * @rsa:		the pointer to SymbianCrypto RSA key. | 
|         |   1260  * | 
|         |   1261  * Sets the value of RSA key data. | 
|         |   1262  * | 
|         |   1263  * Returns 0 on success or a negative value otherwise. | 
|         |   1264  */  | 
|         |   1265 // not needed for current functionality | 
|         |   1266 #ifdef DEBUG  | 
|         |   1267 int | 
|         |   1268 xmlSecSymbianCryptoKeyDataRsaAdoptRsa(xmlSecKeyDataPtr data, RSA* rsa) { | 
|         |   1269     EVP_PKEY* pKey = NULL; | 
|         |   1270     int ret; | 
|         |   1271      | 
|         |   1272     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); | 
|         |   1273      | 
|         |   1274     /* construct new EVP_PKEY */ | 
|         |   1275      | 
|         |   1276 	/* | 
|         |   1277 	ret = EVP_PKEY_assign_RSA(pKey, rsa); | 
|         |   1278 	if(ret != 1) { | 
|         |   1279 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1280 			xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1281 			"EVP_PKEY_assign_RSA", | 
|         |   1282 			XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1283 			XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1284 	    return(-1); | 
|         |   1285 	}	 | 
|         |   1286     } | 
|         |   1287    */ | 
|         |   1288     ret = xmlSecSymbianCryptoKeyDataRsaAdoptEvp(data, pKey); | 
|         |   1289     if(ret < 0) { | 
|         |   1290 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1291 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1292 		    "xmlSecSymbianCryptoKeyDataRsaAdoptEvp", | 
|         |   1293 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1294 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1295 	if(pKey) { | 
|         |   1296 	    EVP_PKEY_free(pKey); | 
|         |   1297 	} | 
|         |   1298 	return(-1); | 
|         |   1299     } | 
|         |   1300      | 
|         |   1301     return(0);     | 
|         |   1302 } | 
|         |   1303 #endif | 
|         |   1304  | 
|         |   1305 /** | 
|         |   1306  * xmlSecSymbianCryptoKeyDataRsaGetRsa: | 
|         |   1307  * @data:		the pointer to RSA key data. | 
|         |   1308  * | 
|         |   1309  * Gets the SymbianCrypto RSA key from RSA key data. | 
|         |   1310  * | 
|         |   1311  * Returns pointer to SymbianCrypto RSA key or NULL if an error occurs. | 
|         |   1312  */ | 
|         |   1313 RSA*  | 
|         |   1314 xmlSecSymbianCryptoKeyDataRsaGetRsa(xmlSecKeyDataPtr data) { | 
|         |   1315     EVP_PKEY* pKey; | 
|         |   1316      | 
|         |   1317     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), NULL); | 
|         |   1318 /*     | 
|         |   1319     pKey = xmlSecSymbianCryptoKeyDataRsaGetEvpTest(data); | 
|         |   1320     xmlSecAssert2((pKey == NULL) || (pKey->type == EVP_PKEY_RSA), NULL); | 
|         |   1321      | 
|         |   1322     return((pKey != NULL) ? pKey->pkey.rsa : (RSA*)NULL); | 
|         |   1323 */     | 
|         |   1324     return NULL; | 
|         |   1325 } | 
|         |   1326  | 
|         |   1327 /**  | 
|         |   1328  * xmlSecSymbianCryptoKeyDataRsaAdoptEvp: | 
|         |   1329  * @data:		the pointer to RSA key data. | 
|         |   1330  * @pKey:		the pointer to SymbianCrypto EVP key. | 
|         |   1331  * | 
|         |   1332  * Sets the RSA key data value to SymbianCrypto EVP key. | 
|         |   1333  * | 
|         |   1334  * Returns 0 on success or a negative value otherwise. | 
|         |   1335  */ | 
|         |   1336 int  | 
|         |   1337 xmlSecSymbianCryptoKeyDataRsaAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) { | 
|         |   1338     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); | 
|         |   1339     xmlSecAssert2(pKey, -1); | 
|         |   1340     xmlSecAssert2(pKey->type == EVP_PKEY_RSA, -1); | 
|         |   1341      | 
|         |   1342     return(xmlSecSymbianCryptoEvpKeyDataAdoptEvp(data, pKey)); | 
|         |   1343 } | 
|         |   1344  | 
|         |   1345 /** | 
|         |   1346  * xmlSecSymbianCryptoKeyDataRsaGetEvp: | 
|         |   1347  * @data:		the pointer to RSA key data. | 
|         |   1348  * | 
|         |   1349  * Gets the SymbianCrypto EVP key from RSA key data. | 
|         |   1350  * | 
|         |   1351  * Returns pointer to SymbianCrypto EVP key or NULL if an error occurs. | 
|         |   1352  */ | 
|         |   1353 EVP_PKEY*  | 
|         |   1354 xmlSecSymbianCryptoKeyDataRsaGetEvpTest(xmlSecKeyDataPtr data) { | 
|         |   1355     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), NULL); | 
|         |   1356  | 
|         |   1357     return(xmlSecSymbianCryptoEvpKeyDataGetEvp(data)); | 
|         |   1358 } | 
|         |   1359  | 
|         |   1360 static int | 
|         |   1361 xmlSecSymbianCryptoKeyDataRsaInitialize(xmlSecKeyDataPtr data) { | 
|         |   1362     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); | 
|         |   1363  | 
|         |   1364     return(xmlSecSymbianCryptoEvpKeyDataInitialize(data)); | 
|         |   1365 } | 
|         |   1366  | 
|         |   1367 static int | 
|         |   1368 xmlSecSymbianCryptoKeyDataRsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { | 
|         |   1369     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecSymbianCryptoKeyDataRsaId), -1); | 
|         |   1370     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecSymbianCryptoKeyDataRsaId), -1); | 
|         |   1371  | 
|         |   1372     return(xmlSecSymbianCryptoEvpKeyDataDuplicate(dst, src)); | 
|         |   1373 } | 
|         |   1374  | 
|         |   1375 static void | 
|         |   1376 xmlSecSymbianCryptoKeyDataRsaFinalize(xmlSecKeyDataPtr data) { | 
|         |   1377     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId)); | 
|         |   1378  | 
|         |   1379     xmlSecSymbianCryptoEvpKeyDataFinalize(data); | 
|         |   1380 } | 
|         |   1381  | 
|         |   1382 static int | 
|         |   1383 xmlSecSymbianCryptoKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, | 
|         |   1384 				    xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { | 
|         |   1385     xmlSecKeyDataPtr data; | 
|         |   1386     xmlNodePtr cur; | 
|         |   1387     RSA *rsa=NULL; | 
|         |   1388     int ret; | 
|         |   1389  | 
|         |   1390     xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataRsaId, -1); | 
|         |   1391     xmlSecAssert2(key, -1); | 
|         |   1392     xmlSecAssert2(node, -1); | 
|         |   1393     xmlSecAssert2(keyInfoCtx, -1); | 
|         |   1394  | 
|         |   1395     if(xmlSecKeyGetValue(key)) { | 
|         |   1396 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1397 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1398 		    NULL,		     | 
|         |   1399 		    XMLSEC_ERRORS_R_INVALID_KEY_DATA, | 
|         |   1400 		    "key already has a value"); | 
|         |   1401 	return(-1);	 | 
|         |   1402     } | 
|         |   1403  | 
|         |   1404     if(!rsa) { | 
|         |   1405 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1406 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1407 		    "RSA_new", | 
|         |   1408 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1409 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1410 	return(-1); | 
|         |   1411     } | 
|         |   1412  | 
|         |   1413     cur = xmlSecGetNextElementNode(node->children); | 
|         |   1414      | 
|         |   1415     /* first is Modulus node. It is REQUIRED because we do not support Seed and PgenCounter*/ | 
|         |   1416     if((!cur) || (!xmlSecCheckNodeName(cur,  xmlSecNodeRSAModulus, xmlSecDSigNs))) { | 
|         |   1417 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1418 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1419 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |   1420 		    XMLSEC_ERRORS_R_INVALID_NODE, | 
|         |   1421 		    "node=%s",  | 
|         |   1422 		    xmlSecErrorsSafeString(xmlSecNodeRSAModulus));	 | 
|         |   1423 	return(-1); | 
|         |   1424     } | 
|         |   1425     /* | 
|         |   1426     if(xmlSecSymbianCryptoNodeGetBNValue(cur, &(rsa->n)) == NULL) { | 
|         |   1427 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1428 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1429 		    "xmlSecSymbianCryptoNodeGetBNValue", | 
|         |   1430 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1431 		    "node=%s",  | 
|         |   1432 		    xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); | 
|         |   1433 	RSA_free(rsa); | 
|         |   1434 	return(-1); | 
|         |   1435     } | 
|         |   1436     */ | 
|         |   1437     cur = xmlSecGetNextElementNode(cur->next); | 
|         |   1438  | 
|         |   1439     /* next is Exponent node. It is REQUIRED because we do not support Seed and PgenCounter*/ | 
|         |   1440     if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAExponent, xmlSecDSigNs))) { | 
|         |   1441 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1442 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1443 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |   1444 		    XMLSEC_ERRORS_R_INVALID_NODE, | 
|         |   1445 		    "node=%s",  | 
|         |   1446 		    xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); | 
|         |   1447 	return(-1); | 
|         |   1448     } | 
|         |   1449     /* | 
|         |   1450     if(xmlSecSymbianCryptoNodeGetBNValue(cur, &(rsa->e)) == NULL) { | 
|         |   1451 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1452 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1453 		    "xmlSecSymbianCryptoNodeGetBNValue", | 
|         |   1454 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1455 		    "node=%s",  | 
|         |   1456 		    xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); | 
|         |   1457 	RSA_free(rsa); | 
|         |   1458 	return(-1); | 
|         |   1459     } | 
|         |   1460     */ | 
|         |   1461     cur = xmlSecGetNextElementNode(cur->next); | 
|         |   1462  | 
|         |   1463     if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeRSAPrivateExponent, xmlSecNs))) { | 
|         |   1464         /* next is X node. It is REQUIRED for private key but | 
|         |   1465 	 * we are not sure exactly what do we read */ | 
|         |   1466 	 /* | 
|         |   1467 	if(xmlSecSymbianCryptoNodeGetBNValue(cur, &(rsa->d)) == NULL) { | 
|         |   1468 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1469 			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1470 			"xmlSecSymbianCryptoNodeGetBNValue", | 
|         |   1471 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1472 			"node=%s",  | 
|         |   1473 			xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); | 
|         |   1474 	    RSA_free(rsa); | 
|         |   1475 	    return(-1); | 
|         |   1476 	} | 
|         |   1477 	*/ | 
|         |   1478 	cur = xmlSecGetNextElementNode(cur->next); | 
|         |   1479     } | 
|         |   1480  | 
|         |   1481     if(cur) { | 
|         |   1482 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1483 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1484 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), | 
|         |   1485 		    XMLSEC_ERRORS_R_INVALID_NODE, | 
|         |   1486 		    "no nodes expected"); | 
|         |   1487 	return(-1); | 
|         |   1488     } | 
|         |   1489  | 
|         |   1490     data = xmlSecKeyDataCreate(id); | 
|         |   1491     if(!data) { | 
|         |   1492 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1493 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1494 		    "xmlSecKeyDataCreate", | 
|         |   1495 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1496 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1497 	return(-1); | 
|         |   1498     } | 
|         |   1499 /* | 
|         |   1500     ret = xmlSecSymbianCryptoKeyDataRsaAdoptRsa(data, rsa); | 
|         |   1501     if(ret < 0) { | 
|         |   1502 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1503 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1504 		    "xmlSecSymbianCryptoKeyDataRsaAdoptRsa", | 
|         |   1505 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1506 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1507 	xmlSecKeyDataDestroy(data); | 
|         |   1508 	//RSA_free(rsa); | 
|         |   1509 	return(-1); | 
|         |   1510     } | 
|         |   1511 */ | 
|         |   1512     ret = xmlSecKeySetValue(key, data); | 
|         |   1513     if(ret < 0) { | 
|         |   1514 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1515 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1516 		    "xmlSecKeySetValue", | 
|         |   1517 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1518 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1519 	xmlSecKeyDataDestroy(data); | 
|         |   1520 	return(-1);	 | 
|         |   1521     } | 
|         |   1522  | 
|         |   1523     return(0); | 
|         |   1524 } | 
|         |   1525  | 
|         |   1526 static int  | 
|         |   1527 xmlSecSymbianCryptoKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, | 
|         |   1528 			    xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { | 
|         |   1529     xmlNodePtr cur; | 
|         |   1530     RSA* rsa; | 
|         |   1531     int ret; | 
|         |   1532      | 
|         |   1533     xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataRsaId, -1); | 
|         |   1534     xmlSecAssert2(key, -1); | 
|         |   1535     xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key),  | 
|         |   1536                                 xmlSecSymbianCryptoKeyDataRsaId), -1); | 
|         |   1537     xmlSecAssert2(node, -1); | 
|         |   1538     xmlSecAssert2(keyInfoCtx, -1); | 
|         |   1539  | 
|         |   1540     rsa = xmlSecSymbianCryptoKeyDataRsaGetRsa(xmlSecKeyGetValue(key)); | 
|         |   1541     xmlSecAssert2(rsa, -1); | 
|         |   1542      | 
|         |   1543     if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) { | 
|         |   1544 	/* we can have only private key or public key */ | 
|         |   1545 	return(0); | 
|         |   1546     }     | 
|         |   1547  | 
|         |   1548     /* first is Modulus node */ | 
|         |   1549     cur = xmlSecAddChild(node, xmlSecNodeRSAModulus, xmlSecDSigNs); | 
|         |   1550     if(!cur) { | 
|         |   1551 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1552 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1553 		    "xmlSecAddChild", | 
|         |   1554 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1555 		    "node=%s",  | 
|         |   1556 		    xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); | 
|         |   1557 	return(-1);	 | 
|         |   1558     } | 
|         |   1559     /* | 
|         |   1560     ret = xmlSecSymbianCryptoNodeSetBNValue(cur, rsa->n, 1); | 
|         |   1561     if(ret < 0) { | 
|         |   1562 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1563 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1564 		    "xmlSecSymbianCryptoNodeSetBNValue", | 
|         |   1565 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1566 		    "node=%s",  | 
|         |   1567 		    xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); | 
|         |   1568 	return(-1); | 
|         |   1569     }     | 
|         |   1570     */ | 
|         |   1571  | 
|         |   1572     /* next is Exponent node. */ | 
|         |   1573     cur = xmlSecAddChild(node, xmlSecNodeRSAExponent, xmlSecDSigNs); | 
|         |   1574     if(!cur) { | 
|         |   1575 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1576 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1577 		    "xmlSecAddChild", | 
|         |   1578 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1579 		    "node=%s",  | 
|         |   1580 		    xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); | 
|         |   1581 	return(-1);	 | 
|         |   1582     } | 
|         |   1583     /* | 
|         |   1584     ret = xmlSecSymbianCryptoNodeSetBNValue(cur, rsa->e, 1); | 
|         |   1585     if(ret < 0) { | 
|         |   1586 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1587 		    xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1588 		    "xmlSecSymbianCryptoNodeSetBNValue", | 
|         |   1589 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1590 		    "node=%s",  | 
|         |   1591 		    xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); | 
|         |   1592 	return(-1); | 
|         |   1593     } | 
|         |   1594 	*/ | 
|         |   1595     /* next is PrivateExponent node: write it ONLY for private keys and ONLY if it is requested */ | 
|         |   1596     /* | 
|         |   1597     if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (rsa->d != NULL)) { | 
|         |   1598 	cur = xmlSecAddChild(node, xmlSecNodeRSAPrivateExponent, xmlSecNs); | 
|         |   1599 	if(cur == NULL) { | 
|         |   1600 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1601 			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1602 			"xmlSecAddChild", | 
|         |   1603 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1604 		        "node=%s",  | 
|         |   1605 			xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); | 
|         |   1606 	    return(-1);	 | 
|         |   1607 	} | 
|         |   1608 	ret = xmlSecSymbianCryptoNodeSetBNValue(cur, rsa->d, 1); | 
|         |   1609 	if(ret < 0) { | 
|         |   1610 	    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1611 			xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), | 
|         |   1612 			"xmlSecSymbianCryptoNodeSetBNValue", | 
|         |   1613 			XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1614 		        "node=%s",  | 
|         |   1615 			xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); | 
|         |   1616 	    return(-1); | 
|         |   1617 	} | 
|         |   1618     } | 
|         |   1619     */ | 
|         |   1620     return(0); | 
|         |   1621 } | 
|         |   1622  | 
|         |   1623 // this routine is modified to fit the interface of evpwrapper.cpp | 
|         |   1624 static int | 
|         |   1625 xmlSecSymbianCryptoKeyDataRsaGenerate(xmlSecKeyDataPtr data,  | 
|         |   1626                             xmlSecSize sizeBits,  | 
|         |   1627                             xmlSecKeyDataType type ATTRIBUTE_UNUSED) { | 
|         |   1628     RSA* rsa; | 
|         |   1629     int ret; | 
|         |   1630     EVP_PKEY *pKey; | 
|         |   1631      | 
|         |   1632     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); | 
|         |   1633     xmlSecAssert2(sizeBits > 0, -1); | 
|         |   1634  | 
|         |   1635 	// Construct new EVP_PKEY | 
|         |   1636 	pKey = sc_pkey_new(EVP_PKEY_RSA, NULL); | 
|         |   1637     if(!pKey) { | 
|         |   1638 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1639 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1640 		    "sc_pkey_key", | 
|         |   1641 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1642 		    "sizeBits=%d", sizeBits); | 
|         |   1643 	return(-1);   | 
|         |   1644     } | 
|         |   1645 	 | 
|         |   1646 	// Check if there is existing key first | 
|         |   1647 	ret = sc_pkey_load(pKey); | 
|         |   1648 	if (ret < -1) {	//KErrNotFound = -1 | 
|         |   1649 	xmlSecSetErrorFlag( ret ); | 
|         |   1650 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1651 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1652 		    "sc_load_key", | 
|         |   1653 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1654 		    "sizeBits=%d", sizeBits); | 
|         |   1655 	return(-1);   | 
|         |   1656     }	 | 
|         |   1657 		 | 
|         |   1658 	// Generate key if key is not found		 | 
|         |   1659 	if (ret == -1)	// KErrNotFound | 
|         |   1660 	{ | 
|         |   1661 		TInt ret2=sc_pkey_generate(pKey, sizeBits); | 
|         |   1662 		if ( ret2 < -1 ) | 
|         |   1663 		{ | 
|         |   1664 		    xmlSecSetErrorFlag( ret2 ); | 
|         |   1665 		    xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1666 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1667 		    "sc_generate_key", | 
|         |   1668 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1669 		    "sizeBits=%d", sizeBits); | 
|         |   1670 	            return(-1);       | 
|         |   1671 		} | 
|         |   1672 	}		 | 
|         |   1673 	if (!pKey->load) { | 
|         |   1674 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1675 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1676 		    "sc_generate_key", | 
|         |   1677 		    XMLSEC_ERRORS_R_CRYPTO_FAILED, | 
|         |   1678 		    "sizeBits=%d", sizeBits); | 
|         |   1679 	return(-1);   | 
|         |   1680     }	 | 
|         |   1681  | 
|         |   1682     ret = xmlSecSymbianCryptoKeyDataRsaAdoptEvp(data, pKey); | 
|         |   1683     if(ret < 0) { | 
|         |   1684 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1685 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1686 		    "xmlSecSymbianCryptoKeyDataRsaAdoptEvp", | 
|         |   1687 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1688 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1689 	if(pKey) { | 
|         |   1690 	    sc_pkey_free(pKey); | 
|         |   1691 	} | 
|         |   1692 	return(-1); | 
|         |   1693     } | 
|         |   1694  | 
|         |   1695  | 
|         |   1696 /* | 
|         |   1697     ret = xmlSecSymbianCryptoKeyDataRsaAdoptRsa(data, rsa); | 
|         |   1698     if(ret < 0) { | 
|         |   1699 	xmlSecError(XMLSEC_ERRORS_HERE, | 
|         |   1700 		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), | 
|         |   1701 		    "xmlSecSymbianCryptoKeyDataRsaAdoptRsa", | 
|         |   1702 		    XMLSEC_ERRORS_R_XMLSEC_FAILED, | 
|         |   1703 		    XMLSEC_ERRORS_NO_MESSAGE); | 
|         |   1704 	RSA_free(rsa); | 
|         |   1705 	return(-1); | 
|         |   1706     } | 
|         |   1707 */ | 
|         |   1708     return(0); | 
|         |   1709 } | 
|         |   1710  | 
|         |   1711 static xmlSecKeyDataType | 
|         |   1712 xmlSecSymbianCryptoKeyDataRsaGetType(xmlSecKeyDataPtr data) { | 
|         |   1713     EVP_PKEY* pkey; | 
|         |   1714      | 
|         |   1715     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId),  | 
|         |   1716                                 xmlSecKeyDataTypeUnknown); | 
|         |   1717      | 
|         |   1718     pkey = xmlSecSymbianCryptoEvpKeyDataGetEvp(data); | 
|         |   1719      | 
|         |   1720     if (pkey->load) | 
|         |   1721     { | 
|         |   1722     	return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); | 
|         |   1723     } | 
|         |   1724     /* | 
|         |   1725     if((rsa != NULL) && (rsa->n != NULL) && (rsa->e != NULL)) { | 
|         |   1726 	if(rsa->d != NULL) { | 
|         |   1727 	    return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); | 
|         |   1728 	} else if(rsa->engine != NULL) { | 
|         |   1729 	*/ | 
|         |   1730 	    /** | 
|         |   1731 	     * | 
|         |   1732 	     * We assume here that engine *always* has private key. | 
|         |   1733 	     * This might be incorrect but it seems that there is no | 
|         |   1734 	     * way to ask engine if given key is private or not. | 
|         |   1735 	     */ | 
|         |   1736 /*	      | 
|         |   1737 	    return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); | 
|         |   1738 	} else { | 
|         |   1739 	    return(xmlSecKeyDataTypePublic); | 
|         |   1740 	} | 
|         |   1741     } | 
|         |   1742 	*/ | 
|         |   1743     return(xmlSecKeyDataTypeUnknown); | 
|         |   1744 } | 
|         |   1745  | 
|         |   1746 static xmlSecSize  | 
|         |   1747 xmlSecSymbianCryptoKeyDataRsaGetSize(xmlSecKeyDataPtr data) { | 
|         |   1748     EVP_PKEY* pkey; | 
|         |   1749  | 
|         |   1750     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), 0); | 
|         |   1751  | 
|         |   1752 	pkey = xmlSecSymbianCryptoEvpKeyDataGetEvp(data); | 
|         |   1753 	if (pkey) | 
|         |   1754 	{ | 
|         |   1755 		return pkey->bitsize; | 
|         |   1756 	} | 
|         |   1757     /* | 
|         |   1758     if((rsa != NULL) && (rsa->n != NULL)) { | 
|         |   1759 	return(BN_num_bits(rsa->n)); | 
|         |   1760     }   | 
|         |   1761     */   | 
|         |   1762     return(0); | 
|         |   1763 } | 
|         |   1764  | 
|         |   1765 static void  | 
|         |   1766 xmlSecSymbianCryptoKeyDataRsaDebugDump(xmlSecKeyDataPtr data, FILE* output) { | 
|         |   1767     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId)); | 
|         |   1768     xmlSecAssert(output); | 
|         |   1769      | 
|         |   1770     fprintf(output, "=== rsa key: size = %d\n",  | 
|         |   1771 	    xmlSecSymbianCryptoKeyDataRsaGetSize(data)); | 
|         |   1772 } | 
|         |   1773  | 
|         |   1774 static void | 
|         |   1775 xmlSecSymbianCryptoKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { | 
|         |   1776     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId)); | 
|         |   1777     xmlSecAssert(output); | 
|         |   1778          | 
|         |   1779     fprintf(output, "<RSAKeyValue size=\"%d\" />\n",  | 
|         |   1780 	    xmlSecSymbianCryptoKeyDataRsaGetSize(data)); | 
|         |   1781 } | 
|         |   1782      | 
|         |   1783 #endif /* XMLSEC_NO_RSA */ | 
|         |   1784  | 
|         |   1785  | 
|         |   1786  | 
|         |   1787  | 
|         |   1788  |