/**
* XMLSec library
*
* This is free software; see Copyright file in the source
* distribution for preciese wording.
*
* Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
* Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
*/
#include "xmlsecc_globals.h"
#include <string.h>
#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) {
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
/**************************************************************************
*
* <dsig:DSAKeyValue> 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:
*
* <element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
* <complexType name="DSAKeyValueType">
* <sequence>
* <sequence minOccurs="0">
* <element name="P" type="ds:CryptoBinary"/>
* <element name="Q" type="ds:CryptoBinary"/>
* </sequence>
* <element name="G" type="ds:CryptoBinary" minOccurs="0"/>
* <element name="Y" type="ds:CryptoBinary"/>
* <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
* <sequence minOccurs="0">
* <element name="Seed" type="ds:CryptoBinary"/>
* <element name="PgenCounter" type="ds:CryptoBinary"/>
* </sequence>
* </sequence>
* </complexType>
*
* DTD Definition:
*
* <!ELEMENT DSAKeyValue ((P, Q)?, G?, Y, J?, (Seed, PgenCounter)?) >
* <!ELEMENT P (#PCDATA) >
* <!ELEMENT Q (#PCDATA) >
* <!ELEMENT G (#PCDATA) >
* <!ELEMENT Y (#PCDATA) >
* <!ELEMENT J (#PCDATA) >
* <!ELEMENT Seed (#PCDATA) >
* <!ELEMENT PgenCounter (#PCDATA) >
*
* ============================================================================
*
* 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, "<DSAKeyValue size=\"%d\" />\n",
xmlSecSymbianCryptoKeyDataDsaGetSize(data));
}
#endif /* XMLSEC_NO_DSA */
#ifndef XMLSEC_NO_RSA
/**************************************************************************
*
* <dsig:RSAKeyValue> processing
*
* http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
* The RSAKeyValue Element
*
* RSA key values have two fields: Modulus and Exponent.
*
* <RSAKeyValue>
* <Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W
* jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV
* 5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=
* </Modulus>
* <Exponent>AQAB</Exponent>
* </RSAKeyValue>
*
* 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:
*
* <element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
* <complexType name="RSAKeyValueType">
* <sequence>
* <element name="Modulus" type="ds:CryptoBinary"/>
* <element name="Exponent" type="ds:CryptoBinary"/>
* </sequence>
* </complexType>
*
* DTD Definition:
*
* <!ELEMENT RSAKeyValue (Modulus, Exponent) >
* <!ELEMENT Modulus (#PCDATA) >
* <!ELEMENT Exponent (#PCDATA) >
*
* ============================================================================
*
* 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) {
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;
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) {
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, "<RSAKeyValue size=\"%d\" />\n",
xmlSecSymbianCryptoKeyDataRsaGetSize(data));
}
#endif /* XMLSEC_NO_RSA */