diff -r 000000000000 -r e35f40988205 xmlsecurityengine/xmlseccrypto/src/xmlsecc_evp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xmlsecurityengine/xmlseccrypto/src/xmlsecc_evp.cpp Thu Dec 17 09:29:21 2009 +0200 @@ -0,0 +1,1788 @@ +/** + * XMLSec library + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2002-2003 Aleksey Sanin + * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. + */ +#include "xmlsecc_globals.h" + +#include +#include "xmlsecc_config.h" +#include "xmlsec_xmlsec.h" +#include "xmlsec_xmltree.h" +#include "xmlsec_keys.h" +#include "xmlsec_keyinfo.h" +#include "xmlsec_transforms.h" +#include "xmlsec_errors.h" +#include "xmlsec_error_flag.h" + +#include "xmlsecc_crypto.h" +#include "xmlsecc_cryptowrapper.h" +#include "xmlsecc_evp.h" + +/************************************************************************** + * + * Internal SymbianCrypto EVP key CTX + * + *************************************************************************/ +typedef struct _xmlSecSymbianCryptoEvpKeyDataCtx xmlSecSymbianCryptoEvpKeyDataCtx, + *xmlSecSymbianCryptoEvpKeyDataCtxPtr; +struct _xmlSecSymbianCryptoEvpKeyDataCtx { + EVP_PKEY* pKey; +}; + +/****************************************************************************** + * + * EVP key (dsa/rsa) + * + * xmlSecSymbianCryptoEvpKeyDataCtx is located after xmlSecTransform + * + *****************************************************************************/ +#define xmlSecSymbianCryptoEvpKeyDataSize \ + (sizeof(xmlSecKeyData) + sizeof(xmlSecSymbianCryptoEvpKeyDataCtx)) +#define xmlSecSymbianCryptoEvpKeyDataGetCtx(data) \ + ((xmlSecSymbianCryptoEvpKeyDataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData))) + +static int xmlSecSymbianCryptoEvpKeyDataInitialize (xmlSecKeyDataPtr data); +static int xmlSecSymbianCryptoEvpKeyDataDuplicate (xmlSecKeyDataPtr dst, + xmlSecKeyDataPtr src); +static void xmlSecSymbianCryptoEvpKeyDataFinalize (xmlSecKeyDataPtr data); + +/** + * xmlSecSymbianCryptoEvpKeyDataAdoptEvp: + * @data: the pointer to SymbianCrypto EVP key data. + * @pKey: the pointer to EVP key. + * + * Sets the value of key data. + * + * Returns 0 on success or a negative value otherwise. + */ +EXPORT_C +int +xmlSecSymbianCryptoEvpKeyDataAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) { + xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); + xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize), -1); + xmlSecAssert2(pKey, -1); + + ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); + xmlSecAssert2(ctx, -1); + + if(ctx->pKey) { + sc_pkey_free(ctx->pKey); + } + ctx->pKey = pKey; + return(0); +} + +/** + * xmlSecSymbianCryptoEvpKeyDataGetEvp: + * @data: the pointer to SymbianCrypto EVP data. + * + * Gets the EVP_PKEY from the key data. + * + * Returns pointer to EVP_PKEY or NULL if an error occurs. + */ +EXPORT_C +EVP_PKEY* +xmlSecSymbianCryptoEvpKeyDataGetEvp(xmlSecKeyDataPtr data) { + xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL); + xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize), NULL); + + ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); + xmlSecAssert2(ctx, NULL); + + return(ctx->pKey); + + return NULL; +} + +static int +xmlSecSymbianCryptoEvpKeyDataInitialize(xmlSecKeyDataPtr data) { + xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataIsValid(data), -1); + xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize), -1); + + ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); + xmlSecAssert2(ctx, -1); + + memset(ctx, 0, sizeof(xmlSecSymbianCryptoEvpKeyDataCtx)); + + return(0); +} + +static int +xmlSecSymbianCryptoEvpKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { + xmlSecSymbianCryptoEvpKeyDataCtxPtr ctxDst; + xmlSecSymbianCryptoEvpKeyDataCtxPtr ctxSrc; + + xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1); + xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecSymbianCryptoEvpKeyDataSize), -1); + xmlSecAssert2(xmlSecKeyDataIsValid(src), -1); + xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecSymbianCryptoEvpKeyDataSize), -1); + + ctxDst = xmlSecSymbianCryptoEvpKeyDataGetCtx(dst); + xmlSecAssert2(ctxDst, -1); + xmlSecAssert2(!ctxDst->pKey, -1); + + ctxSrc = xmlSecSymbianCryptoEvpKeyDataGetCtx(src); + xmlSecAssert2(ctxSrc, -1); + + if(ctxSrc->pKey) { + ctxDst->pKey = xmlSecSymbianCryptoEvpKeyDup(ctxSrc->pKey); + ctxDst->pKey->duplicate=0; + ctxSrc->pKey->duplicate=1; + if(!ctxDst->pKey) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)), + "xmlSecSymbianCryptoEvpKeyDup", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + + return(0); +} + +static void +xmlSecSymbianCryptoEvpKeyDataFinalize(xmlSecKeyDataPtr data) { + xmlSecSymbianCryptoEvpKeyDataCtxPtr ctx; + + xmlSecAssert(xmlSecKeyDataIsValid(data)); + xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecSymbianCryptoEvpKeyDataSize)); + + ctx = xmlSecSymbianCryptoEvpKeyDataGetCtx(data); + xmlSecAssert(ctx); + + if(ctx->pKey) { + sc_pkey_free(ctx->pKey); + } + memset(ctx, 0, sizeof(xmlSecSymbianCryptoEvpKeyDataCtx)); + +} +/**************************************************************************** + * + * Symbian Keys Store + * + ***************************************************************************/ +#define xmlSecSymbianKeysStoreSize \ + (sizeof(xmlSecKeyStore)+ sizeof(xmlSecPtrList)) +#define xmlSecSymbianKeysStoreGetList(store) \ + ((xmlSecKeyStoreCheckSize((store), xmlSecSymbianKeysStoreSize)) ? \ + (xmlSecPtrListPtr)(((xmlSecByte*)(store)) + sizeof(xmlSecKeyStore)) : \ + (xmlSecPtrListPtr)NULL) + + +static xmlSecKeyPtr xmlSecSymbianKeysStoreFindKey (xmlSecKeyStorePtr store, + const xmlChar* name, + xmlSecKeyInfoCtxPtr keyInfoCtx); + +static xmlSecKeyStoreKlass xmlSecSymbianKeysStoreKlass = { + sizeof(xmlSecKeyStoreKlass), + xmlSecSymbianKeysStoreSize, + + /* data */ + BAD_CAST "symbian-keys-store", /* const xmlChar* name; */ + + /* constructors/destructor */ + NULL, /* xmlSecKeyStoreInitializeMethod initialize; */ + NULL, /* xmlSecKeyStoreFinalizeMethod finalize; */ + xmlSecSymbianKeysStoreFindKey, /* xmlSecKeyStoreFindKeyMethod findKey; */ + + /* reserved for the future */ + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecSymbianKeysStoreGetKlass: + * + * The Symbian list based keys store klass. + * + * Returns simple list based keys store klass. + */ +EXPORT_C +xmlSecKeyStoreId +xmlSecSymbianKeysStoreGetKlass(void) { + return(&xmlSecSymbianKeysStoreKlass); +} + + +static xmlSecKeyPtr +xmlSecSymbianKeysStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name, + xmlSecKeyInfoCtxPtr keyInfoCtx) { + + xmlSecKeyPtr key=NULL; + + xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSymbianKeysStoreId), NULL); + xmlSecAssert2(keyInfoCtx, NULL); + + if((!name) || (keyInfoCtx->keyReq.keyId == xmlSecKeyDataIdUnknown)){ + return(NULL); + } + if(keyInfoCtx->keyReq.keyId== xmlSecSymbianCryptoKeyDataRsaId) { + + key=xmlSecSymbianCryptoAppKeyLoadSks((char*)name); + if(!key) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSymbianKeysStoreFindKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "name=%s", + xmlSecErrorsSafeString(name)); + return(NULL); + } + + } + return(key); +} +/** + * xmlSecSymbianCryptoAppKeyLoadSks: + * @keyname: the key name. + * + * Reads key from the symbian keystore. + * + * Returns pointer to the key or NULL if an error occurs. + */ +EXPORT_C +xmlSecKeyPtr +xmlSecSymbianCryptoAppKeyLoadSks(char* keyname) { + + xmlSecKeyPtr key = NULL; + xmlSecKeyDataPtr data; + EVP_PKEY* pKey = NULL; + + int ret; + + xmlSecAssert2(keyname, NULL); + + pKey = d2i_PKCS8PrivateKey(keyname); + if(!pKey) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "sc_PrivateKey_read", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + data = xmlSecSymbianCryptoEvpKeyAdopt(pKey); + if(!data) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSymbianCryptoEvpKeyAdopt", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + sc_pkey_free(pKey); + return(NULL); + } + + key = xmlSecKeyCreate(); + if(!key) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(data); + return(NULL); + } + + ret = xmlSecKeySetValue(key, data); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "data=%s", + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data))); + xmlSecKeyDestroy(key); + xmlSecKeyDataDestroy(data); + return(NULL); + } + + return(key); +} +/****************************************************************************** + * + * EVP helper functions + * + *****************************************************************************/ +/** + * xmlSecSymbianCryptoEvpKeyDup: + * @pKey: the pointer to EVP_PKEY. + * + * Duplicates @pKey. + * + * Returns pointer to newly created EVP_PKEY object or NULL if an error occurs. + */ +EXPORT_C +EVP_PKEY* +xmlSecSymbianCryptoEvpKeyDup(EVP_PKEY* pKey) { + int ret; + EVP_PKEY* pKeyNew; + + xmlSecAssert2(pKey, NULL); + + pKeyNew = sc_pkey_duplicate(pKey); + if(!pKeyNew) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "sc_pkey_duplicate", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + return (pKeyNew); +} + +/** + * xmlSecSymbianCryptoEvpKeyAdopt: + * @pKey: the pointer to EVP_PKEY. + * + * Creates xmlsec key object from SymbianCrypto key object. + * + * Returns pointer to newly created xmlsec key or NULL if an error occurs. + */ +EXPORT_C +xmlSecKeyDataPtr +xmlSecSymbianCryptoEvpKeyAdopt(EVP_PKEY *pKey) { + xmlSecKeyDataPtr data = NULL; + int ret; + + xmlSecAssert2(pKey, NULL); + + switch(pKey->type) { +#ifndef XMLSEC_NO_RSA + case EVP_PKEY_RSA: + data = xmlSecKeyDataCreate(xmlSecSymbianCryptoKeyDataRsaId); + if(!data) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecSymbianCryptoKeyDataRsaId"); + return(NULL); + } + break; +#endif /* XMLSEC_NO_RSA */ +#ifndef XMLSEC_NO_DSA + case EVP_PKEY_DSA: + data = xmlSecKeyDataCreate(xmlSecSymbianCryptoKeyDataDsaId); + if(!data) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecSymbianCryptoKeyDataDsaId"); + return(NULL); + } + break; +#endif /* XMLSEC_NO_DSA */ + default: + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_INVALID_TYPE, + "evp key type %d not supported", pKey->type); + return(NULL); + } + + xmlSecAssert2(data, NULL); + ret = xmlSecSymbianCryptoEvpKeyDataAdoptEvp(data, pKey); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSymbianCryptoEvpKeyDataAdoptEvp", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(data); + return(NULL); + } + return(data); +} + +#ifndef XMLSEC_NO_DSA +/************************************************************************** + * + * processing + * + * + * The DSAKeyValue Element (http://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue) + * + * DSA keys and the DSA signature algorithm are specified in [DSS]. + * DSA public key values can have the following fields: + * + * * P - a prime modulus meeting the [DSS] requirements + * * Q - an integer in the range 2**159 < Q < 2**160 which is a prime + * divisor of P-1 + * * G - an integer with certain properties with respect to P and Q + * * Y - G**X mod P (where X is part of the private key and not made + * public) + * * J - (P - 1) / Q + * * seed - a DSA prime generation seed + * * pgenCounter - a DSA prime generation counter + * + * Parameter J is available for inclusion solely for efficiency as it is + * calculatable from P and Q. Parameters seed and pgenCounter are used in the + * DSA prime number generation algorithm specified in [DSS]. As such, they are + * optional but must either both be present or both be absent. This prime + * generation algorithm is designed to provide assurance that a weak prime is + * not being used and it yields a P and Q value. Parameters P, Q, and G can be + * public and common to a group of users. They might be known from application + * context. As such, they are optional but P and Q must either both appear or + * both be absent. If all of P, Q, seed, and pgenCounter are present, + * implementations are not required to check if they are consistent and are + * free to use either P and Q or seed and pgenCounter. All parameters are + * encoded as base64 [MIME] values. + * + * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are + * represented in XML as octet strings as defined by the ds:CryptoBinary type. + * + * Schema Definition: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * DTD Definition: + * + * + * + * + * + * + * + * + * + * + * ============================================================================ + * + * To support reading/writing private keys an X element added (before Y). + * Note: The current implementation does not support Seed and PgenCounter! + * by this the P, Q and G are *required*! + * + *************************************************************************/ +static int xmlSecSymbianCryptoKeyDataDsaInitialize (xmlSecKeyDataPtr data); +static int xmlSecSymbianCryptoKeyDataDsaDuplicate (xmlSecKeyDataPtr dst, + xmlSecKeyDataPtr src); +static void xmlSecSymbianCryptoKeyDataDsaFinalize (xmlSecKeyDataPtr data); +static int xmlSecSymbianCryptoKeyDataDsaXmlRead (xmlSecKeyDataId id, + xmlSecKeyPtr key, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecSymbianCryptoKeyDataDsaXmlWrite (xmlSecKeyDataId id, + xmlSecKeyPtr key, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecSymbianCryptoKeyDataDsaGenerate (xmlSecKeyDataPtr data, + xmlSecSize sizeBits, + xmlSecKeyDataType type); + +static xmlSecKeyDataType xmlSecSymbianCryptoKeyDataDsaGetType (xmlSecKeyDataPtr data); +static xmlSecSize xmlSecSymbianCryptoKeyDataDsaGetSize (xmlSecKeyDataPtr data); +static void xmlSecSymbianCryptoKeyDataDsaDebugDump (xmlSecKeyDataPtr data, + FILE* output); +static void xmlSecSymbianCryptoKeyDataDsaDebugXmlDump (xmlSecKeyDataPtr data, + FILE* output); + +static xmlSecKeyDataKlass xmlSecSymbianCryptoKeyDataDsaKlass = { + sizeof(xmlSecKeyDataKlass), + xmlSecSymbianCryptoEvpKeyDataSize, + + /* data */ + xmlSecNameDSAKeyValue, + xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, + /* xmlSecKeyDataUsage usage; */ + xmlSecHrefDSAKeyValue, /* const xmlChar* href; */ + xmlSecNodeDSAKeyValue, /* const xmlChar* dataNodeName; */ + xmlSecDSigNs, /* const xmlChar* dataNodeNs; */ + + /* constructors/destructor */ + xmlSecSymbianCryptoKeyDataDsaInitialize, /* xmlSecKeyDataInitializeMethod initialize; */ + xmlSecSymbianCryptoKeyDataDsaDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ + xmlSecSymbianCryptoKeyDataDsaFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */ + xmlSecSymbianCryptoKeyDataDsaGenerate, /* xmlSecKeyDataGenerateMethod generate; */ + + /* get info */ + xmlSecSymbianCryptoKeyDataDsaGetType, /* xmlSecKeyDataGetTypeMethod getType; */ + xmlSecSymbianCryptoKeyDataDsaGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */ + NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ + + /* read/write */ + xmlSecSymbianCryptoKeyDataDsaXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ + xmlSecSymbianCryptoKeyDataDsaXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ + NULL, /* xmlSecKeyDataBinReadMethod binRead; */ + NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */ + + /* debug */ + xmlSecSymbianCryptoKeyDataDsaDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ + xmlSecSymbianCryptoKeyDataDsaDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ + + /* reserved for the future */ + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecSymbianCryptoKeyDataDsaGetKlass: + * + * The DSA key data klass. + * + * Returns pointer to DSA key data klass. + */ +xmlSecKeyDataId +xmlSecSymbianCryptoKeyDataDsaGetKlass(void) { + return(&xmlSecSymbianCryptoKeyDataDsaKlass); +} + +/** + * xmlSecSymbianCryptoKeyDataDsaAdoptDsa: + * @data: the pointer to DSA key data. + * @dsa: the pointer to SymbianCrypto DSA key. + * + * Sets the value of DSA key data. + * + * Returns 0 on success or a negative value otherwise. + */ +int +xmlSecSymbianCryptoKeyDataDsaAdoptDsa(xmlSecKeyDataPtr data, DSA* dsa) { + EVP_PKEY* pKey = NULL; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); + + /* construct new EVP_PKEY */ + if(dsa) { + pKey = EVP_PKEY_new(); + if(!pKey) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "EVP_PKEY_new", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = EVP_PKEY_assign_DSA(pKey, dsa); + if(ret != 1) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "EVP_PKEY_assign_DSA", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + + ret = xmlSecSymbianCryptoKeyDataDsaAdoptEvp(data, pKey); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecSymbianCryptoKeyDataDsaAdoptEvp", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + if(pKey) { + EVP_PKEY_free(pKey); + } + return(-1); + } + return(0); +} + +/** + * xmlSecSymbianCryptoKeyDataDsaGetDsa: + * @data: the pointer to DSA key data. + * + * Gets the SymbianCrypto DSA key from DSA key data. + * + * Returns pointer to SymbianCrypto DSA key or NULL if an error occurs. + */ +DSA* +xmlSecSymbianCryptoKeyDataDsaGetDsa(xmlSecKeyDataPtr data) { + EVP_PKEY* pKey; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), NULL); + + pKey = xmlSecSymbianCryptoKeyDataDsaGetEvp(data); + xmlSecAssert2((!pKey) || (pKey->type == EVP_PKEY_DSA), NULL); + + return((pKey) ? pKey->pkey.dsa : (DSA*)NULL); +} + +/** + * xmlSecSymbianCryptoKeyDataDsaAdoptEvp: + * @data: the pointer to DSA key data. + * @pKey: the pointer to SymbianCrypto EVP key. + * + * Sets the DSA key data value to SymbianCrypto EVP key. + * + * Returns 0 on success or a negative value otherwise. + */ +int +xmlSecSymbianCryptoKeyDataDsaAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); + xmlSecAssert2(pKey, -1); + xmlSecAssert2(pKey->type == EVP_PKEY_DSA, -1); + + return(xmlSecSymbianCryptoEvpKeyDataAdoptEvp(data, pKey)); +} + +/** + * xmlSecSymbianCryptoKeyDataDsaGetEvp: + * @data: the pointer to DSA key data. + * + * Gets the SymbianCrypto EVP key from DSA key data. + * + * Returns pointer to SymbianCrypto EVP key or NULL if an error occurs. + */ +EVP_PKEY* +xmlSecSymbianCryptoKeyDataDsaGetEvp(xmlSecKeyDataPtr data) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), NULL); + + return(xmlSecSymbianCryptoEvpKeyDataGetEvp(data)); +} + +static int +xmlSecSymbianCryptoKeyDataDsaInitialize(xmlSecKeyDataPtr data) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); + + return(xmlSecSymbianCryptoEvpKeyDataInitialize(data)); +} + +static int +xmlSecSymbianCryptoKeyDataDsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { + xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecSymbianCryptoKeyDataDsaId), -1); + xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecSymbianCryptoKeyDataDsaId), -1); + + return(xmlSecSymbianCryptoEvpKeyDataDuplicate(dst, src)); +} + +static void +xmlSecSymbianCryptoKeyDataDsaFinalize(xmlSecKeyDataPtr data) { + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId)); + + xmlSecSymbianCryptoEvpKeyDataFinalize(data); +} + +static int +xmlSecSymbianCryptoKeyDataDsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, + xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataPtr data; + xmlNodePtr cur; + DSA *dsa; + int ret; + + xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataDsaId, -1); + xmlSecAssert2(key, -1); + xmlSecAssert2(node, -1); + xmlSecAssert2(keyInfoCtx, -1); + + if(xmlSecKeyGetValue(key)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + NULL, + XMLSEC_ERRORS_R_INVALID_KEY_DATA, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + dsa = DSA_new(); + if(!dsa) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "DSA_new", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + cur = xmlSecGetNextElementNode(node->children); + + /* first is P node. It is REQUIRED because we do not support Seed and PgenCounter*/ + if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAP, xmlSecDSigNs))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAP)); + DSA_free(dsa); + return(-1); + } + if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->p))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAP)); + DSA_free(dsa); + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + + /* next is Q node. It is REQUIRED because we do not support Seed and PgenCounter*/ + if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAQ, xmlSecDSigNs))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAQ)); + DSA_free(dsa); + return(-1); + } + if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->q))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAQ)); + DSA_free(dsa); + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + + /* next is G node. It is REQUIRED because we do not support Seed and PgenCounter*/ + if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAG, xmlSecDSigNs))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAG)); + DSA_free(dsa); + return(-1); + } + if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->g))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAG)); + DSA_free(dsa); + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + + if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAX, xmlSecNs))) { + /* next is X node. It is REQUIRED for private key but + * we are not sure exactly what do we read */ + if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->priv_key))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAX)); + DSA_free(dsa); + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + } + + /* next is Y node. */ + if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAY, xmlSecDSigNs))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAY)); + DSA_free(dsa); + return(-1); + } + if(!xmlSecSymbianCryptoNodeGetBNValue(cur, &(dsa->pub_key))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", xmlSecErrorsSafeString(xmlSecNodeDSAY)); + DSA_free(dsa); + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + + if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAJ, xmlSecDSigNs))) { + cur = xmlSecGetNextElementNode(cur->next); + } + + if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSASeed, xmlSecDSigNs))) { + cur = xmlSecGetNextElementNode(cur->next); + } + + if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAPgenCounter, xmlSecDSigNs))) { + cur = xmlSecGetNextElementNode(cur->next); + } + + if(cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_UNEXPECTED_NODE, + XMLSEC_ERRORS_NO_MESSAGE); + DSA_free(dsa); + return(-1); + } + + data = xmlSecKeyDataCreate(id); + if(!data) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + DSA_free(dsa); + return(-1); + } + + ret = xmlSecSymbianCryptoKeyDataDsaAdoptDsa(data, dsa); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecSymbianCryptoKeyDataDsaAdoptDsa", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(data); + DSA_free(dsa); + return(-1); + } + + ret = xmlSecKeySetValue(key, data); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(data); + return(-1); + } + + return(0); +} + +static int +xmlSecSymbianCryptoKeyDataDsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, + xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlNodePtr cur; + DSA* dsa; + int ret; + + xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataDsaId, -1); + xmlSecAssert2(key, -1); + xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), + xmlSecSymbianCryptoKeyDataDsaId), -1); + xmlSecAssert2(node, -1); + xmlSecAssert2(keyInfoCtx, -1); + + dsa = xmlSecSymbianCryptoKeyDataDsaGetDsa(xmlSecKeyGetValue(key)); + xmlSecAssert2(dsa, -1); + + if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) { + /* we can have only private key or public key */ + return(0); + } + + /* first is P node */ + xmlSecAssert2(dsa->p, -1); + cur = xmlSecAddChild(node, xmlSecNodeDSAP, xmlSecDSigNs); + if(!cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAP)); + return(-1); + } + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->p, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAP)); + return(-1); + } + + /* next is Q node. */ + xmlSecAssert2(dsa->q, -1); + cur = xmlSecAddChild(node, xmlSecNodeDSAQ, xmlSecDSigNs); + if(!cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAQ)); + return(-1); + } + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->q, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAQ)); + return(-1); + } + + /* next is G node. */ + xmlSecAssert2(dsa->g, -1); + cur = xmlSecAddChild(node, xmlSecNodeDSAG, xmlSecDSigNs); + if(!cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAG)); + return(-1); + } + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->g, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAG)); + return(-1); + } + + /* next is X node: write it ONLY for private keys and ONLY if it is requested */ + if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (dsa->priv_key)) { + cur = xmlSecAddChild(node, xmlSecNodeDSAX, xmlSecNs); + if(!cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAX)); + return(-1); + } + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->priv_key, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAX)); + return(-1); + } + } + + /* next is Y node. */ + xmlSecAssert2(dsa->pub_key, -1); + cur = xmlSecAddChild(node, xmlSecNodeDSAY, xmlSecDSigNs); + if(!cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAY)); + return(-1); + } + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, dsa->pub_key, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeDSAY)); + return(-1); + } + return(0); +} + +static int +xmlSecSymbianCryptoKeyDataDsaGenerate(xmlSecKeyDataPtr data, + xmlSecSize sizeBits, + xmlSecKeyDataType type ATTRIBUTE_UNUSED) { + DSA* dsa; + int counter_ret; + unsigned long h_ret; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), -1); + xmlSecAssert2(sizeBits > 0, -1); + + dsa = DSA_generate_parameters(sizeBits, NULL, 0, &counter_ret, &h_ret, NULL, NULL); + if(!dsa) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "DSA_generate_parameters", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "size=%d", sizeBits); + return(-1); + } + + ret = DSA_generate_key(dsa); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "DSA_generate_key", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + DSA_free(dsa); + return(-1); + } + + ret = xmlSecSymbianCryptoKeyDataDsaAdoptDsa(data, dsa); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecSymbianCryptoKeyDataDsaAdoptDsa", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + DSA_free(dsa); + return(-1); + } + + return(0); +} + +static xmlSecKeyDataType +xmlSecSymbianCryptoKeyDataDsaGetType(xmlSecKeyDataPtr data) { + DSA* dsa; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), + xmlSecKeyDataTypeUnknown); + + dsa = xmlSecSymbianCryptoKeyDataDsaGetDsa(data); + if((dsa) && (dsa->p) && (dsa->q) && + (dsa->g) && (dsa->pub_key)) { + + if(dsa->priv_key) { + return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); + } else if(dsa->engine) { + /** + * + * We assume here that engine *always* has private key. + * This might be incorrect but it seems that there is no + * way to ask engine if given key is private or not. + */ + return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); + } else { + return(xmlSecKeyDataTypePublic); + } + } + + return(xmlSecKeyDataTypeUnknown); +} + +static xmlSecSize +xmlSecSymbianCryptoKeyDataDsaGetSize(xmlSecKeyDataPtr data) { + DSA* dsa; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId), 0); + + dsa = xmlSecSymbianCryptoKeyDataDsaGetDsa(data); + if((dsa) && (dsa->p)) { + return(BN_num_bits(dsa->p)); + } + return(0); +} + +static void +xmlSecSymbianCryptoKeyDataDsaDebugDump(xmlSecKeyDataPtr data, FILE* output) { + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId)); + xmlSecAssert(output); + + fprintf(output, "=== dsa key: size = %d\n", + xmlSecSymbianCryptoKeyDataDsaGetSize(data)); +} + +static void +xmlSecSymbianCryptoKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataDsaId)); + xmlSecAssert(output); + + fprintf(output, "\n", + xmlSecSymbianCryptoKeyDataDsaGetSize(data)); +} + +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_RSA +/************************************************************************** + * + * processing + * + * http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue + * The RSAKeyValue Element + * + * RSA key values have two fields: Modulus and Exponent. + * + * + * xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W + * jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV + * 5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U= + * + * AQAB + * + * + * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are + * represented in XML as octet strings as defined by the ds:CryptoBinary type. + * + * Schema Definition: + * + * + * + * + * + * + * + * + * + * DTD Definition: + * + * + * + * + * + * ============================================================================ + * + * To support reading/writing private keys an PrivateExponent element is added + * to the end + * + *************************************************************************/ + +static int xmlSecSymbianCryptoKeyDataRsaInitialize (xmlSecKeyDataPtr data); +static int xmlSecSymbianCryptoKeyDataRsaDuplicate (xmlSecKeyDataPtr dst, + xmlSecKeyDataPtr src); +static void xmlSecSymbianCryptoKeyDataRsaFinalize (xmlSecKeyDataPtr data); +static int xmlSecSymbianCryptoKeyDataRsaXmlRead (xmlSecKeyDataId id, + xmlSecKeyPtr key, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecSymbianCryptoKeyDataRsaXmlWrite (xmlSecKeyDataId id, + xmlSecKeyPtr key, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecSymbianCryptoKeyDataRsaGenerate (xmlSecKeyDataPtr data, + xmlSecSize sizeBits, + xmlSecKeyDataType type); + +static xmlSecKeyDataType xmlSecSymbianCryptoKeyDataRsaGetType (xmlSecKeyDataPtr data); +static xmlSecSize xmlSecSymbianCryptoKeyDataRsaGetSize (xmlSecKeyDataPtr data); +static void xmlSecSymbianCryptoKeyDataRsaDebugDump (xmlSecKeyDataPtr data, + FILE* output); +static void xmlSecSymbianCryptoKeyDataRsaDebugXmlDump (xmlSecKeyDataPtr data, + FILE* output); +static xmlSecKeyDataKlass xmlSecSymbianCryptoKeyDataRsaKlass = { + sizeof(xmlSecKeyDataKlass), + xmlSecSymbianCryptoEvpKeyDataSize, + + /* data */ + xmlSecNameRSAKeyValue, + xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, + /* xmlSecKeyDataUsage usage; */ + xmlSecHrefRSAKeyValue, /* const xmlChar* href; */ + xmlSecNodeRSAKeyValue, /* const xmlChar* dataNodeName; */ + xmlSecDSigNs, /* const xmlChar* dataNodeNs; */ + + /* constructors/destructor */ + xmlSecSymbianCryptoKeyDataRsaInitialize, /* xmlSecKeyDataInitializeMethod initialize; */ + xmlSecSymbianCryptoKeyDataRsaDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ + xmlSecSymbianCryptoKeyDataRsaFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */ + xmlSecSymbianCryptoKeyDataRsaGenerate, /* xmlSecKeyDataGenerateMethod generate; */ + + /* get info */ + xmlSecSymbianCryptoKeyDataRsaGetType, /* xmlSecKeyDataGetTypeMethod getType; */ + xmlSecSymbianCryptoKeyDataRsaGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */ + NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ + + /* read/write */ + xmlSecSymbianCryptoKeyDataRsaXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ + xmlSecSymbianCryptoKeyDataRsaXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ + NULL, /* xmlSecKeyDataBinReadMethod binRead; */ + NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */ + + /* debug */ + xmlSecSymbianCryptoKeyDataRsaDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ + xmlSecSymbianCryptoKeyDataRsaDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ + + /* reserved for the future */ + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecSymbianCryptoKeyDataRsaGetKlass: + * + * The SymbianCrypto RSA key data klass. + * + * Returns pointer to SymbianCrypto RSA key data klass. + */ +EXPORT_C +xmlSecKeyDataId +xmlSecSymbianCryptoKeyDataRsaGetKlass(void) { + return(&xmlSecSymbianCryptoKeyDataRsaKlass); +} + +/** + * xmlSecSymbianCryptoKeyDataRsaAdoptRsa: + * @data: the pointer to RSA key data. + * @rsa: the pointer to SymbianCrypto RSA key. + * + * Sets the value of RSA key data. + * + * Returns 0 on success or a negative value otherwise. + */ +// not needed for current functionality +#ifdef DEBUG +int +xmlSecSymbianCryptoKeyDataRsaAdoptRsa(xmlSecKeyDataPtr data, RSA* rsa) { + EVP_PKEY* pKey = NULL; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); + + /* construct new EVP_PKEY */ + + /* + ret = EVP_PKEY_assign_RSA(pKey, rsa); + if(ret != 1) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "EVP_PKEY_assign_RSA", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + */ + ret = xmlSecSymbianCryptoKeyDataRsaAdoptEvp(data, pKey); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecSymbianCryptoKeyDataRsaAdoptEvp", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + if(pKey) { + EVP_PKEY_free(pKey); + } + return(-1); + } + + return(0); +} +#endif + +/** + * xmlSecSymbianCryptoKeyDataRsaGetRsa: + * @data: the pointer to RSA key data. + * + * Gets the SymbianCrypto RSA key from RSA key data. + * + * Returns pointer to SymbianCrypto RSA key or NULL if an error occurs. + */ +RSA* +xmlSecSymbianCryptoKeyDataRsaGetRsa(xmlSecKeyDataPtr data) { + EVP_PKEY* pKey; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), NULL); +/* + pKey = xmlSecSymbianCryptoKeyDataRsaGetEvpTest(data); + xmlSecAssert2((pKey == NULL) || (pKey->type == EVP_PKEY_RSA), NULL); + + return((pKey != NULL) ? pKey->pkey.rsa : (RSA*)NULL); +*/ + return NULL; +} + +/** + * xmlSecSymbianCryptoKeyDataRsaAdoptEvp: + * @data: the pointer to RSA key data. + * @pKey: the pointer to SymbianCrypto EVP key. + * + * Sets the RSA key data value to SymbianCrypto EVP key. + * + * Returns 0 on success or a negative value otherwise. + */ +int +xmlSecSymbianCryptoKeyDataRsaAdoptEvp(xmlSecKeyDataPtr data, EVP_PKEY* pKey) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); + xmlSecAssert2(pKey, -1); + xmlSecAssert2(pKey->type == EVP_PKEY_RSA, -1); + + return(xmlSecSymbianCryptoEvpKeyDataAdoptEvp(data, pKey)); +} + +/** + * xmlSecSymbianCryptoKeyDataRsaGetEvp: + * @data: the pointer to RSA key data. + * + * Gets the SymbianCrypto EVP key from RSA key data. + * + * Returns pointer to SymbianCrypto EVP key or NULL if an error occurs. + */ +EVP_PKEY* +xmlSecSymbianCryptoKeyDataRsaGetEvpTest(xmlSecKeyDataPtr data) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), NULL); + + return(xmlSecSymbianCryptoEvpKeyDataGetEvp(data)); +} + +static int +xmlSecSymbianCryptoKeyDataRsaInitialize(xmlSecKeyDataPtr data) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); + + return(xmlSecSymbianCryptoEvpKeyDataInitialize(data)); +} + +static int +xmlSecSymbianCryptoKeyDataRsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { + xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecSymbianCryptoKeyDataRsaId), -1); + xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecSymbianCryptoKeyDataRsaId), -1); + + return(xmlSecSymbianCryptoEvpKeyDataDuplicate(dst, src)); +} + +static void +xmlSecSymbianCryptoKeyDataRsaFinalize(xmlSecKeyDataPtr data) { + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId)); + + xmlSecSymbianCryptoEvpKeyDataFinalize(data); +} + +static int +xmlSecSymbianCryptoKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, + xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataPtr data; + xmlNodePtr cur; + RSA *rsa=NULL; + int ret; + + xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataRsaId, -1); + xmlSecAssert2(key, -1); + xmlSecAssert2(node, -1); + xmlSecAssert2(keyInfoCtx, -1); + + if(xmlSecKeyGetValue(key)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + NULL, + XMLSEC_ERRORS_R_INVALID_KEY_DATA, + "key already has a value"); + return(-1); + } + + if(!rsa) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "RSA_new", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + cur = xmlSecGetNextElementNode(node->children); + + /* first is Modulus node. It is REQUIRED because we do not support Seed and PgenCounter*/ + if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAModulus, xmlSecDSigNs))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); + return(-1); + } + /* + if(xmlSecSymbianCryptoNodeGetBNValue(cur, &(rsa->n)) == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); + RSA_free(rsa); + return(-1); + } + */ + cur = xmlSecGetNextElementNode(cur->next); + + /* next is Exponent node. It is REQUIRED because we do not support Seed and PgenCounter*/ + if((!cur) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAExponent, xmlSecDSigNs))) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); + return(-1); + } + /* + if(xmlSecSymbianCryptoNodeGetBNValue(cur, &(rsa->e)) == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); + RSA_free(rsa); + return(-1); + } + */ + cur = xmlSecGetNextElementNode(cur->next); + + if((cur) && (xmlSecCheckNodeName(cur, xmlSecNodeRSAPrivateExponent, xmlSecNs))) { + /* next is X node. It is REQUIRED for private key but + * we are not sure exactly what do we read */ + /* + if(xmlSecSymbianCryptoNodeGetBNValue(cur, &(rsa->d)) == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeGetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); + RSA_free(rsa); + return(-1); + } + */ + cur = xmlSecGetNextElementNode(cur->next); + } + + if(cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE, + "no nodes expected"); + return(-1); + } + + data = xmlSecKeyDataCreate(id); + if(!data) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } +/* + ret = xmlSecSymbianCryptoKeyDataRsaAdoptRsa(data, rsa); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoKeyDataRsaAdoptRsa", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(data); + //RSA_free(rsa); + return(-1); + } +*/ + ret = xmlSecKeySetValue(key, data); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(data); + return(-1); + } + + return(0); +} + +static int +xmlSecSymbianCryptoKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, + xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlNodePtr cur; + RSA* rsa; + int ret; + + xmlSecAssert2(id == xmlSecSymbianCryptoKeyDataRsaId, -1); + xmlSecAssert2(key, -1); + xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), + xmlSecSymbianCryptoKeyDataRsaId), -1); + xmlSecAssert2(node, -1); + xmlSecAssert2(keyInfoCtx, -1); + + rsa = xmlSecSymbianCryptoKeyDataRsaGetRsa(xmlSecKeyGetValue(key)); + xmlSecAssert2(rsa, -1); + + if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) { + /* we can have only private key or public key */ + return(0); + } + + /* first is Modulus node */ + cur = xmlSecAddChild(node, xmlSecNodeRSAModulus, xmlSecDSigNs); + if(!cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); + return(-1); + } + /* + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, rsa->n, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAModulus)); + return(-1); + } + */ + + /* next is Exponent node. */ + cur = xmlSecAddChild(node, xmlSecNodeRSAExponent, xmlSecDSigNs); + if(!cur) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); + return(-1); + } + /* + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, rsa->e, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAExponent)); + return(-1); + } + */ + /* next is PrivateExponent node: write it ONLY for private keys and ONLY if it is requested */ + /* + if(((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) && (rsa->d != NULL)) { + cur = xmlSecAddChild(node, xmlSecNodeRSAPrivateExponent, xmlSecNs); + if(cur == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); + return(-1); + } + ret = xmlSecSymbianCryptoNodeSetBNValue(cur, rsa->d, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecSymbianCryptoNodeSetBNValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeRSAPrivateExponent)); + return(-1); + } + } + */ + return(0); +} + +// this routine is modified to fit the interface of evpwrapper.cpp +static int +xmlSecSymbianCryptoKeyDataRsaGenerate(xmlSecKeyDataPtr data, + xmlSecSize sizeBits, + xmlSecKeyDataType type ATTRIBUTE_UNUSED) { + RSA* rsa; + int ret; + EVP_PKEY *pKey; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), -1); + xmlSecAssert2(sizeBits > 0, -1); + + // Construct new EVP_PKEY + pKey = sc_pkey_new(EVP_PKEY_RSA, NULL); + if(!pKey) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "sc_pkey_key", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "sizeBits=%d", sizeBits); + return(-1); + } + + // Check if there is existing key first + ret = sc_pkey_load(pKey); + if (ret < -1) { //KErrNotFound = -1 + xmlSecSetErrorFlag( ret ); + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "sc_load_key", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "sizeBits=%d", sizeBits); + return(-1); + } + + // Generate key if key is not found + if (ret == -1) // KErrNotFound + { + TInt ret2=sc_pkey_generate(pKey, sizeBits); + if ( ret2 < -1 ) + { + xmlSecSetErrorFlag( ret2 ); + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "sc_generate_key", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "sizeBits=%d", sizeBits); + return(-1); + } + } + if (!pKey->load) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "sc_generate_key", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "sizeBits=%d", sizeBits); + return(-1); + } + + ret = xmlSecSymbianCryptoKeyDataRsaAdoptEvp(data, pKey); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecSymbianCryptoKeyDataRsaAdoptEvp", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + if(pKey) { + sc_pkey_free(pKey); + } + return(-1); + } + + +/* + ret = xmlSecSymbianCryptoKeyDataRsaAdoptRsa(data, rsa); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecSymbianCryptoKeyDataRsaAdoptRsa", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + RSA_free(rsa); + return(-1); + } +*/ + return(0); +} + +static xmlSecKeyDataType +xmlSecSymbianCryptoKeyDataRsaGetType(xmlSecKeyDataPtr data) { + EVP_PKEY* pkey; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), + xmlSecKeyDataTypeUnknown); + + pkey = xmlSecSymbianCryptoEvpKeyDataGetEvp(data); + + if (pkey->load) + { + return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); + } + /* + if((rsa != NULL) && (rsa->n != NULL) && (rsa->e != NULL)) { + if(rsa->d != NULL) { + return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); + } else if(rsa->engine != NULL) { + */ + /** + * + * We assume here that engine *always* has private key. + * This might be incorrect but it seems that there is no + * way to ask engine if given key is private or not. + */ +/* + return(xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic); + } else { + return(xmlSecKeyDataTypePublic); + } + } + */ + return(xmlSecKeyDataTypeUnknown); +} + +static xmlSecSize +xmlSecSymbianCryptoKeyDataRsaGetSize(xmlSecKeyDataPtr data) { + EVP_PKEY* pkey; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId), 0); + + pkey = xmlSecSymbianCryptoEvpKeyDataGetEvp(data); + if (pkey) + { + return pkey->bitsize; + } + /* + if((rsa != NULL) && (rsa->n != NULL)) { + return(BN_num_bits(rsa->n)); + } + */ + return(0); +} + +static void +xmlSecSymbianCryptoKeyDataRsaDebugDump(xmlSecKeyDataPtr data, FILE* output) { + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId)); + xmlSecAssert(output); + + fprintf(output, "=== rsa key: size = %d\n", + xmlSecSymbianCryptoKeyDataRsaGetSize(data)); +} + +static void +xmlSecSymbianCryptoKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecSymbianCryptoKeyDataRsaId)); + xmlSecAssert(output); + + fprintf(output, "\n", + xmlSecSymbianCryptoKeyDataRsaGetSize(data)); +} + +#endif /* XMLSEC_NO_RSA */ + + + + +