--- /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 <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) {
+ 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
+/**************************************************************************
+ *
+ * <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) {
+ 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, "<RSAKeyValue size=\"%d\" />\n",
+ xmlSecSymbianCryptoKeyDataRsaGetSize(data));
+}
+
+#endif /* XMLSEC_NO_RSA */
+
+
+
+
+