Projekt

Allgemein

Profil

Herunterladen (40,8 KB) Statistiken
| Zweig: | Markierung: | Revision:
/***************************************************************************
$RCSfile$
-------------------
cvs : $Id$
begin : Sat Nov 15 2003
copyright : (C) 2003 by Martin Preuss
email : martin@libchipcard.de

***************************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA *
* *
***************************************************************************/



#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "ipcxmlsecctx_p.h"
#include <gwenhywfar/misc.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/text.h>
#include <gwenhywfar/md.h>
#include <gwenhywfar/crypt.h>
#include <gwenhywfar/directory.h>
#include <gwenhywfar/ipc.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>



GWEN_IPCXMLSECCTXDATA *GWEN_IPCXMLSecCtxData_new(){
GWEN_IPCXMLSECCTXDATA *d;

GWEN_NEW_OBJECT(GWEN_IPCXMLSECCTXDATA, d);
return d;
}



void GWEN_IPCXMLSecCtxData_free(GWEN_IPCXMLSECCTXDATA *d){
if (d) {
GWEN_CryptKey_free(d->sessionKey);
free(d->serviceCode);
free(d->securityId);
GWEN_CryptKey_free(d->localSignKey);
GWEN_CryptKey_free(d->localCryptKey);
GWEN_CryptKey_free(d->remoteSignKey);
GWEN_CryptKey_free(d->remoteCryptKey);
free(d);
}
}



GWEN_CRYPTKEY *GWEN_IPCXMLSecCtx_GetSessionKey(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->sessionKey;
}



void GWEN_IPCXMLSecCtx_SetSessionKey(GWEN_SECCTX *sc,
GWEN_CRYPTKEY *k){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

GWEN_CryptKey_free(scd->sessionKey);
scd->sessionKey=k;
}



const GWEN_CRYPTKEY *GWEN_IPCXMLSecCtx_GetLocalSignKey(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->localSignKey;
}



const GWEN_CRYPTKEY *GWEN_IPCXMLSecCtx_GetLocalCryptKey(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->localCryptKey;
}



const GWEN_CRYPTKEY *GWEN_IPCXMLSecCtx_GetRemoteSignKey(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->remoteSignKey;
}



const GWEN_CRYPTKEY *GWEN_IPCXMLSecCtx_GetRemoteCryptKey(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->remoteCryptKey;
}



GWEN_SECCTX_RETVAL GWEN_IPCXMLSecCtx_PrepareCTX(GWEN_SECCTX *sc,
GWEN_HBCICRYPTOCONTEXT *ctx,
int crypt){
GWEN_IPCXMLSECCTXDATA *scd;
GWEN_ERRORCODE err;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

if (crypt) {
if (scd->remoteCryptKey==0) {
DBG_ERROR(0, "No remote crypt key");
return GWEN_SecCtxRetvalError;
}
GWEN_HBCICryptoContext_SetKeySpec(ctx,
GWEN_CryptKey_GetKeySpec(scd->remoteCryptKey));
if (!(scd->sessionKey)) {
GWEN_BUFFER *kbuf;
GWEN_BUFFER *sbuf;
int i;

/* generate session key, if possible */
DBG_NOTICE(0, "Generating session key");
scd->sessionKey=GWEN_CryptKey_Factory("DES");
assert(scd->sessionKey);
err=GWEN_CryptKey_Generate(scd->sessionKey, 0);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO_ERR(0, err);
return GWEN_SecCtxRetvalError;
}
kbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_ReserveBytes(kbuf, 128);
if (GWEN_Buffer_AppendBytes(kbuf,
GWEN_CryptKey_GetKeyData(scd->sessionKey),
16)) {
DBG_INFO(0, "here");
GWEN_Buffer_free(kbuf);
return GWEN_SecCtxRetvalError;
}

GWEN_Buffer_Rewind(kbuf);
i=GWEN_CryptKey_GetChunkSize(scd->remoteCryptKey)-16;
DBG_INFO(0, "Padding with %d bytes", i);
while(i-->0) {
if (GWEN_Buffer_InsertByte(kbuf, (char)0)) {
DBG_INFO(0, "here");
GWEN_Buffer_free(kbuf);
return GWEN_SecCtxRetvalError;
}
} /* while */
DBG_INFO(0, "Padding done");

sbuf=GWEN_Buffer_new(0, 256, 0, 1);
DBG_INFO(0, "Encrypting key");
err=GWEN_CryptKey_Encrypt(scd->remoteCryptKey,
kbuf,
sbuf);
if (!GWEN_Error_IsOk(err)) {
GWEN_Buffer_free(kbuf);
GWEN_Buffer_free(sbuf);
DBG_INFO_ERR(0, err);
return GWEN_SecCtxRetvalError;
}
DBG_INFO(0, "Encrypting key: done");

GWEN_HBCICryptoContext_SetCryptKey(ctx,
GWEN_Buffer_GetStart(sbuf),
GWEN_Buffer_GetUsedBytes(sbuf));
GWEN_Buffer_free(kbuf);
GWEN_Buffer_free(sbuf);
} /* if no session key */
}
else {
if (scd->localSignKey==0) {
DBG_ERROR(0, "No local sign key");
return GWEN_SecCtxRetvalError;
}
GWEN_HBCICryptoContext_SetKeySpec(ctx,
GWEN_CryptKey_GetKeySpec(scd->localSignKey));
/* sign */
GWEN_HBCICryptoContext_SetSequenceNum(ctx,
GWEN_IPCXMLSecCtx_GetLocalSignSeq(sc));
}

GWEN_HBCICryptoContext_SetMode(ctx, "RDH");
if (scd->serviceCode)
GWEN_HBCICryptoContext_SetServiceCode(ctx, scd->serviceCode);
if (scd->securityId)
GWEN_HBCICryptoContext_SetSecurityId(ctx,
scd->securityId,
strlen(scd->securityId)+1);
DBG_INFO(0, "Context prepared");
return GWEN_SecCtxRetvalOk;
}



GWEN_SECCTX_RETVAL GWEN_IPCXMLSecCtx_Sign(GWEN_SECCTX *sc,
GWEN_BUFFER *msgbuf,
GWEN_BUFFER *signbuf,
GWEN_HBCICRYPTOCONTEXT *ctx){
GWEN_IPCXMLSECCTXDATA *scd;
GWEN_MD *md;
GWEN_BUFFER *hashbuf;
GWEN_ERRORCODE err;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

if (scd->localSignKey==0) {
DBG_ERROR(0, "No local sign key");
return GWEN_SecCtxRetvalError;
}

/* hash data */
DBG_INFO(0, "Hash data");
md=GWEN_MD_Factory("RMD160");
if (!md) {
DBG_ERROR(0, "RMD160 not found");
return GWEN_SecCtxRetvalError;
}

if (GWEN_MD_Begin(md)) {
DBG_INFO(0, "here");
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}

if (GWEN_MD_Update(md,
GWEN_Buffer_GetStart(msgbuf),
GWEN_Buffer_GetUsedBytes(msgbuf))) {
DBG_INFO(0, "here");
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}

if (GWEN_MD_End(md)) {
DBG_INFO(0, "here");
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}
DBG_INFO(0, "Hashing done");

hashbuf=GWEN_Buffer_new(0,
GWEN_MD_GetDigestSize(md),
0, 1);
if (GWEN_Buffer_AppendBytes(hashbuf,
(const char*)GWEN_MD_GetDigestPtr(md),
GWEN_MD_GetDigestSize(md))) {
DBG_INFO(0, "here");
GWEN_Buffer_free(hashbuf);
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}
GWEN_MD_free(md);

/* padd */
DBG_INFO(0, "Padding hash using ISO 9796");
if (GWEN_SecContext_PaddWithISO9796(hashbuf)) {
DBG_INFO(0, "here");
GWEN_Buffer_free(hashbuf);
return GWEN_SecCtxRetvalError;
}

/* sign hash */
GWEN_Buffer_Rewind(hashbuf);
err=GWEN_CryptKey_Sign(scd->localSignKey,
hashbuf,
signbuf);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO_ERR(0, err);
GWEN_Buffer_free(hashbuf);
return err;
}

/* increment signature counter */
scd->localSignSeq++;

GWEN_Buffer_free(hashbuf);
DBG_INFO(0, "Signing done");
return GWEN_SecCtxRetvalOk;
}



GWEN_SECCTX_RETVAL GWEN_IPCXMLSecCtx_Verify(GWEN_SECCTX *sc,
GWEN_BUFFER *msgbuf,
GWEN_BUFFER *signbuf,
GWEN_HBCICRYPTOCONTEXT *ctx){
GWEN_IPCXMLSECCTXDATA *scd;
GWEN_MD *md;
GWEN_BUFFER *hashbuf;
GWEN_ERRORCODE err;
unsigned int rseq;
const GWEN_KEYSPEC *ks, *ks2;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

if (scd->remoteSignKey==0) {
DBG_ERROR(0, "No remote sign key");
return GWEN_SecCtxRetvalUnknown;
}

/* verify that the key is the one we know */
ks=GWEN_HBCICryptoContext_GetKeySpec(ctx);
assert(ks);
ks2=GWEN_CryptKey_GetKeySpec(scd->remoteSignKey);
assert(ks2);
if (!(
(GWEN_Text_Compare(GWEN_KeySpec_GetOwner(ks),
GWEN_KeySpec_GetOwner(ks2),1)==0) &&
(GWEN_Text_Compare(GWEN_KeySpec_GetKeyName(ks),
GWEN_KeySpec_GetKeyName(ks2),1)==0) &&
(GWEN_KeySpec_GetNumber(ks)==GWEN_KeySpec_GetNumber(ks2)) &&
(GWEN_KeySpec_GetVersion(ks)==GWEN_KeySpec_GetVersion(ks2))
)) {
DBG_ERROR(0,
"Remote sign key differs from that one used for signing");
return GWEN_SecCtxRetvalError;
}


/* check signature sequence number */
rseq=GWEN_HBCICryptoContext_GetSequenceNum(ctx);
if (rseq<=GWEN_IPCXMLSecCtx_GetRemoteSignSeq(sc)) {
DBG_ERROR(0, "bad signature sequence number (%d<%d)",
rseq, GWEN_IPCXMLSecCtx_GetRemoteSignSeq(sc));
return GWEN_SecCtxRetvalError; /* comment this out for debugging */
}
GWEN_IPCXMLSecCtx_SetRemoteSignSeq(sc, rseq);

/* hash data */
md=GWEN_MD_Factory("RMD160");
if (!md) {
DBG_ERROR(0, "RMD160 not found");
return GWEN_SecCtxRetvalError;
}

if (GWEN_MD_Begin(md)) {
DBG_INFO(0, "here");
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}

if (GWEN_MD_Update(md,
GWEN_Buffer_GetStart(msgbuf),
GWEN_Buffer_GetUsedBytes(msgbuf))) {
DBG_INFO(0, "here");
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}

if (GWEN_MD_End(md)) {
DBG_INFO(0, "here");
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}

hashbuf=GWEN_Buffer_new(0, GWEN_MD_GetDigestSize(md), 0, 1);
if (GWEN_Buffer_AppendBytes(hashbuf,
(const char*)GWEN_MD_GetDigestPtr(md),
GWEN_MD_GetDigestSize(md))) {
DBG_INFO(0, "here");
GWEN_Buffer_free(hashbuf);
GWEN_MD_free(md);
return GWEN_SecCtxRetvalError;
}
GWEN_MD_free(md);

/* padd */
DBG_INFO(0, "Padding hash using ISO 9796");
if (GWEN_SecContext_PaddWithISO9796(hashbuf)) {
DBG_INFO(0, "here");
GWEN_Buffer_free(hashbuf);
return GWEN_SecCtxRetvalError;
}

/* verify hash */
err=GWEN_CryptKey_Verify(scd->remoteSignKey,
hashbuf,
signbuf);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO_ERR(0, err);
GWEN_Buffer_free(hashbuf);
return GWEN_SecCtxRetvalError;
}
GWEN_Buffer_free(hashbuf);

return GWEN_SecCtxRetvalOk;
}



GWEN_SECCTX_RETVAL GWEN_IPCXMLSecCtx_Encrypt(GWEN_SECCTX *sc,
GWEN_BUFFER *msgbuf,
GWEN_BUFFER *cryptbuf,
GWEN_HBCICRYPTOCONTEXT *ctx){
GWEN_IPCXMLSECCTXDATA *scd;
GWEN_ERRORCODE err;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

if (!(scd->sessionKey)) {
DBG_ERROR(0, "No session key");
return GWEN_SecCtxRetvalError;
}

DBG_INFO(0, "Padding with ANSI X9.23");
if (GWEN_SecContext_PaddWithANSIX9_23(msgbuf)) {
DBG_INFO(0, "here");
return GWEN_SecCtxRetvalError;
}
DBG_INFO(0, "Padding with ANSI X9.23: done");

DBG_INFO(0, "Encrypting with session key");
err=GWEN_CryptKey_Encrypt(scd->sessionKey,
msgbuf,
cryptbuf);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO(0, "here");
return GWEN_SecCtxRetvalError;
}
DBG_INFO(0, "Encrypting with session key: done");

return GWEN_SecCtxRetvalOk;
}



GWEN_SECCTX_RETVAL GWEN_IPCXMLSecCtx_Decrypt(GWEN_SECCTX *sc,
GWEN_BUFFER *msgbuf,
GWEN_BUFFER *decryptbuf,
GWEN_HBCICRYPTOCONTEXT *ctx){
GWEN_IPCXMLSECCTXDATA *scd;
GWEN_ERRORCODE err;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

if (GWEN_HBCICryptoContext_GetCryptKeyPtr(ctx)) {
/* new session key, store it */
GWEN_BUFFER *kbuf;
GWEN_BUFFER *sbuf;
GWEN_CRYPTKEY *key;
const GWEN_KEYSPEC *ks, *ks2;
char *km;

DBG_NOTICE(0, "Storing new session key");
sbuf=GWEN_Buffer_new(0, 256, 0, 1);
if (GWEN_Buffer_AppendBytes(sbuf,
GWEN_HBCICryptoContext_GetCryptKeyPtr(ctx),
GWEN_HBCICryptoContext_GetCryptKeySize(ctx))){
DBG_INFO(0, "here");
GWEN_Buffer_free(sbuf);
return GWEN_SecCtxRetvalError;
}
kbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_Rewind(sbuf);
if (scd->localCryptKey==0) {
DBG_ERROR(0, "No local crypt key");
return GWEN_SecCtxRetvalError;
}

/* verify that the key is the one we know */
ks=GWEN_HBCICryptoContext_GetKeySpec(ctx);
assert(ks);
ks2=GWEN_CryptKey_GetKeySpec(scd->localCryptKey);
assert(ks2);
if (!(
(GWEN_Text_Compare(GWEN_KeySpec_GetOwner(ks),
GWEN_KeySpec_GetOwner(ks2),1)==0) &&
(GWEN_Text_Compare(GWEN_KeySpec_GetKeyName(ks),
GWEN_KeySpec_GetKeyName(ks2),1)==0) &&
(GWEN_KeySpec_GetNumber(ks)==GWEN_KeySpec_GetNumber(ks2)) &&
(GWEN_KeySpec_GetVersion(ks)==GWEN_KeySpec_GetVersion(ks2))
)) {
DBG_ERROR(0,
"Local crypt key differs from that one used for encryption");
return GWEN_SecCtxRetvalError;
}

err=GWEN_CryptKey_Decrypt(scd->localCryptKey,
sbuf,
kbuf);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO(0, "here");
GWEN_Buffer_free(sbuf);
GWEN_Buffer_free(kbuf);
return GWEN_SecCtxRetvalError;
}

key=GWEN_CryptKey_Factory("DES");
assert(key);
km=(char*)malloc(16);
assert(km);
memmove(km,
GWEN_Buffer_GetStart(kbuf)+
GWEN_Buffer_GetUsedBytes(kbuf)-16,
16);

GWEN_CryptKey_SetKeyData(key, km);
GWEN_Buffer_free(sbuf);
GWEN_Buffer_free(kbuf);
GWEN_CryptKey_free(scd->sessionKey);
scd->sessionKey=key;
}

/* now decrypt the message */
err=GWEN_CryptKey_Decrypt(scd->sessionKey,
msgbuf,
decryptbuf);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO(0, "here");
return GWEN_SecCtxRetvalError;
}

if (GWEN_SecContext_UnpaddWithANSIX9_23(decryptbuf)) {
DBG_INFO(0, "here");
return GWEN_SecCtxRetvalError;
}

return GWEN_SecCtxRetvalOk;
}



void GWEN_IPCXMLSecCtx_FreeData(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

DBG_ERROR(0, "Freeing SecCtx-Data");
GWEN_IPCXMLSecCtxData_free(scd);
}



void GWEN_IPCXMLSecCtx_Reset(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

GWEN_CryptKey_free(scd->sessionKey);
scd->sessionKey=0;
}



const char *GWEN_IPCXMLSecCtx_GetServiceCode(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->serviceCode;
}



void GWEN_IPCXMLSecCtx_SetServiceCode(GWEN_SECCTX *sc,
const char *s){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
assert(s);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

free(scd->serviceCode);
scd->serviceCode=strdup(s);
}



const char *GWEN_IPCXMLSecCtx_GetSecurityId(GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->securityId;
}



void GWEN_IPCXMLSecCtx_SetSecurityId(GWEN_SECCTX *sc,
const char *s){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
assert(s);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

free(scd->securityId);
scd->securityId=strdup(s);
}



unsigned int GWEN_IPCXMLSecCtx_GetLocalSignSeq(GWEN_SECCTX *sc) {
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->localSignSeq;
}



void GWEN_IPCXMLSecCtx_SetLocalSignSeq(GWEN_SECCTX *sc,
unsigned int i) {
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

scd->localSignSeq=i;
}



unsigned int GWEN_IPCXMLSecCtx_GetRemoteSignSeq(GWEN_SECCTX *sc) {
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

return scd->remoteSignSeq;
}



void GWEN_IPCXMLSecCtx_SetRemoteSignSeq(GWEN_SECCTX *sc,
unsigned int i) {
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

scd->remoteSignSeq=i;
}



GWEN_SECCTX *GWEN_IPCXMLSecCtx_new(const char *localName,
const char *remoteName){
GWEN_SECCTX *sc;
GWEN_IPCXMLSECCTXDATA *scd;

sc=GWEN_SecContext_new(localName, remoteName);
scd=GWEN_IPCXMLSecCtxData_new();
scd->localSignSeq=1;
scd->remoteSignSeq=0;

GWEN_SecContext_SetPrepareCtxFn(sc, GWEN_IPCXMLSecCtx_PrepareCTX);
GWEN_SecContext_SetSignFn(sc, GWEN_IPCXMLSecCtx_Sign);
GWEN_SecContext_SetVerifyFn(sc, GWEN_IPCXMLSecCtx_Verify);
GWEN_SecContext_SetEncryptFn(sc, GWEN_IPCXMLSecCtx_Encrypt);
GWEN_SecContext_SetDecrpytFn(sc, GWEN_IPCXMLSecCtx_Decrypt);
GWEN_SecContext_SetFreeDataFn(sc, GWEN_IPCXMLSecCtx_FreeData);
GWEN_SecContext_SetFromDbFn(sc, GWEN_IPCXMLSecCtx_FromDB);
GWEN_SecContext_SetToDbFn(sc, GWEN_IPCXMLSecCtx_ToDB);

GWEN_SecContext_SetData(sc, scd);

return sc;
}


GWEN_SECCTX_RETVAL GWEN_IPCXMLSecCtx_FromDB(GWEN_SECCTX *sc,
GWEN_DB_NODE *db){
const char *p;
GWEN_DB_NODE *gr;
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=GWEN_IPCXMLSecCtxData_new();
assert(scd);
scd->localSignSeq=GWEN_DB_GetIntValue(db, "localsignseq", 0, 0);
scd->remoteSignSeq=GWEN_DB_GetIntValue(db, "remotesignseq", 0, 0);
p=GWEN_DB_GetCharValue(db, "serviceCode", 0, 0);
if (p)
GWEN_IPCXMLSecCtx_SetServiceCode(sc, p);
p=GWEN_DB_GetCharValue(db, "securityId", 0, 0);
if (p)
GWEN_IPCXMLSecCtx_SetSecurityId(sc, p);

/* read the keys */
gr=GWEN_DB_GetGroup(db,
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_NAMEMUSTEXIST,
"remotesignkey");
if (gr) {
GWEN_CryptKey_free(scd->remoteSignKey);
scd->remoteSignKey=GWEN_CryptKey_FromDb(gr);
if (scd->remoteSignKey==0) {
DBG_ERROR(0, "Could not read key");
return GWEN_SecCtxRetvalError;
}
} /* if "remotesignkey" group */

gr=GWEN_DB_GetGroup(db,
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_NAMEMUSTEXIST,
"remotecryptkey");
if (gr) {
GWEN_CryptKey_free(scd->remoteCryptKey);
scd->remoteCryptKey=GWEN_CryptKey_FromDb(gr);
if (scd->remoteCryptKey==0) {
DBG_ERROR(0, "Could not read key");
return GWEN_SecCtxRetvalError;
}
} /* if "remotecryptkey" group */

GWEN_SecContext_SetData(sc, scd);
return GWEN_SecCtxRetvalOk;
}



GWEN_SECCTX_RETVAL GWEN_IPCXMLSecCtx_ToDB(GWEN_SECCTX *sc,
GWEN_DB_NODE *db){
GWEN_IPCXMLSECCTXDATA *scd;
GWEN_DB_NODE *gr;
GWEN_ERRORCODE err;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

GWEN_DB_SetIntValue(db,
GWEN_DB_FLAGS_DEFAULT |
GWEN_DB_FLAGS_OVERWRITE_VARS,
"localsignseq",
scd->localSignSeq);
GWEN_DB_SetIntValue(db,
GWEN_DB_FLAGS_DEFAULT |
GWEN_DB_FLAGS_OVERWRITE_VARS,
"remotesignseq",
scd->remoteSignSeq);
if (scd->remoteSignKey) {
gr=GWEN_DB_GetGroup(db,
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_CREATE_GROUP,
"remotesignkey");
assert(gr);
err=GWEN_CryptKey_ToDb(scd->remoteSignKey, gr, 1);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO_ERR(0, err);
return GWEN_SecCtxRetvalError;
}
}

if (scd->remoteCryptKey) {
gr=GWEN_DB_GetGroup(db,
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_CREATE_GROUP,
"remotecryptkey");
assert(gr);
err=GWEN_CryptKey_ToDb(scd->remoteCryptKey, gr, 1);
if (!GWEN_Error_IsOk(err)) {
DBG_INFO_ERR(0, err);
return GWEN_SecCtxRetvalError;
}
}

return GWEN_SecCtxRetvalOk;
}



void GWEN_IPCXMLSecCtx_SetLocalSignKey(GWEN_SECCTX *sc,
const GWEN_CRYPTKEY *key){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

assert(key);
if (scd->localSignKey)
GWEN_CryptKey_free(scd->localSignKey);
scd->localSignKey=GWEN_CryptKey_dup(key);
}



void GWEN_IPCXMLSecCtx_SetLocalCryptKey(GWEN_SECCTX *sc,
const GWEN_CRYPTKEY *key){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

assert(key);
if (scd->localCryptKey)
GWEN_CryptKey_free(scd->localCryptKey);
scd->localCryptKey=GWEN_CryptKey_dup(key);
}



GWEN_ERRORCODE GWEN_IPCXMLSecCtx_SetRemoteSignKey(GWEN_SECCTX *sc,
GWEN_CRYPTKEY *key){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

if (scd->remoteSignKey &&
!(GWEN_SecContext_GetFlags(sc) &
GWEN_SECCTX_FLAGS_ALLOW_KEY_CHANGE)) {
DBG_ERROR(0, "There already is a sign key");
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
GWEN_Error_FindType(GWEN_IPC_ERROR_TYPE),
GWEN_IPC_ERROR_INVALID);
}
GWEN_CryptKey_free(scd->remoteSignKey);
scd->remoteSignKey=key;
return 0;
}



GWEN_ERRORCODE GWEN_IPCXMLSecCtx_SetRemoteCryptKey(GWEN_SECCTX *sc,
GWEN_CRYPTKEY *key){
GWEN_IPCXMLSECCTXDATA *scd;

assert(sc);
scd=(GWEN_IPCXMLSECCTXDATA*)GWEN_SecContext_GetData(sc);
assert(scd);

if (scd->remoteCryptKey &&
!(GWEN_SecContext_GetFlags(sc) &
GWEN_SECCTX_FLAGS_ALLOW_KEY_CHANGE)) {
DBG_ERROR(0, "There already is a crypt key");
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
GWEN_Error_FindType(GWEN_IPC_ERROR_TYPE),
GWEN_IPC_ERROR_INVALID);
}
GWEN_CryptKey_free(scd->remoteCryptKey);
scd->remoteCryptKey=key;
return 0;
}






GWEN_SECCTX *GWEN_IPCXMLSecCtxtMgr_FindContext(GWEN_SECCTX_MANAGER *scm,
const char *localName,
const char *remoteName){
GWEN_LIST_ITERATOR *it;
GWEN_IPCXMLSECCTXMGRDATA *scmd;

assert(scm);
assert(localName);
assert(remoteName);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);
assert(scmd->contextList);

DBG_WARN(0, "Looking for context \"%s:%s\"", localName, remoteName);
it=GWEN_List_First(scmd->contextList);
if (it) {
GWEN_SECCTX *sc;

sc=(GWEN_SECCTX*)GWEN_ListIterator_Data(it);
while(sc) {
if ((GWEN_Text_Compare(GWEN_SecContext_GetLocalName(sc),
localName, 1)==0) &&
(GWEN_Text_Compare(GWEN_SecContext_GetRemoteName(sc),
remoteName, 1)==0)){
GWEN_ListIterator_free(it);
return sc;
}
sc=(GWEN_SECCTX*)GWEN_ListIterator_Next(it);
} /* while */
}
GWEN_ListIterator_free(it);

DBG_INFO(0, "Context \"%s:%s\" not found.", localName, remoteName);
return 0;
}



int GWEN_IPCXMLSecCtxMgr_LockFile(const char *path) {
int fid;
struct flock fl;

if (GWEN_Directory_GetPath(path, GWEN_PATH_FLAGS_VARIABLE)) {
DBG_ERROR(0, "Could not create path \"%s\"", path);
return -1;
}

/* file exists, try to open it */
fid=open(path, O_RDWR);
if (fid==-1) {
DBG_ERROR(0, "Error on open(%s): %s",
path, strerror(errno));
return -1;
}

/* now lock it (wait for lock if necessary) */
fl.l_type=F_WRLCK;
fl.l_whence=SEEK_SET;
fl.l_start=0;
fl.l_len=0;
if (fcntl(fid, F_SETLKW, &fl)) {
close(fid);
DBG_ERROR(0, "Error on fcntl(%s, F_SETLKW): %s",
path, strerror(errno));
return -1;
}
return fid;
}



int GWEN_IPCXMLSecCtxMgr_UnlockFile(int fid) {
struct flock fl;

/* unlock file */
fl.l_type=F_UNLCK;
fl.l_whence=SEEK_SET;
fl.l_start=0;
fl.l_len=0;
if (fcntl(fid, F_SETLKW, &fl)) {
close(fid);
DBG_ERROR(0, "Error on fcntl(%d, F_SETLKW): %s",
fid, strerror(errno));
return -1;
}
if (close(fid)) {
DBG_ERROR(0, "Error on close(%d): %s",
fid, strerror(errno));
return -1;
}
return 0;
}




GWEN_SECCTX *GWEN_IPCXMLSecCtxMgr_GetContext(GWEN_SECCTX_MANAGER *scm,
const char *localName,
const char *remoteName){
GWEN_IPCXMLSECCTXMGRDATA *scmd;
char path[256];

assert(scm);
assert(localName);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);
assert(scmd->dir);

if (remoteName) {
/* try to read the file */
DBG_INFO(0, "Trying to read context \"%s:%s\"",
localName, remoteName);
if (strlen(scmd->dir)+
strlen(localName)+
strlen(remoteName)+
4>sizeof(path)) {
DBG_ERROR(0, "Path too long");
return 0;
}
strcpy(path, scmd->dir);
strcat(path, "/");
strcat(path, localName);
strcat(path, "/");
strcat(path, remoteName);
strcat(path, ".ctx");
if (GWEN_Directory_GetPath(path,
GWEN_PATH_FLAGS_VARIABLE |
GWEN_PATH_FLAGS_PATHMUSTEXIST)) {
GWEN_SECCTX *ctx;

DBG_INFO(0,
"File for context \"%s:%s\" not found, will check for tmp",
localName, remoteName);
ctx=GWEN_IPCXMLSecCtxtMgr_FindContext(scm,
localName,
remoteName);
if (!ctx) {
DBG_INFO(0, "Context \"%s:%s\" not found",
localName, remoteName);
return 0;
}
GWEN_SecContext_SetFlags(ctx, GWEN_SECCTX_FLAGS_TEMP);
if (GWEN_IPCXMLSecCtx_GetLocalSignKey(ctx)==0 &&
scmd->localSignKey)
GWEN_IPCXMLSecCtx_SetLocalSignKey(ctx,scmd->localSignKey);
if (GWEN_IPCXMLSecCtx_GetLocalCryptKey(ctx)==0 &&
scmd->localCryptKey)
GWEN_IPCXMLSecCtx_SetLocalCryptKey(ctx,scmd->localCryptKey);
return ctx;
}
else {
GWEN_DB_NODE *db;
GWEN_SECCTX *ctx;
int fid;

DBG_INFO(0, "Trying to load file for context \"%s:%s\"",
localName, remoteName);
/* file exists, try to lock it */
fid=GWEN_IPCXMLSecCtxMgr_LockFile(path);
if (fid==-1) {
return 0;
}

/* try to read the file */
db=GWEN_DB_Group_new("context");
if (GWEN_DB_ReadFile(db, path,
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_CREATE_GROUP)) {
DBG_ERROR(0, "Error reading file \"%s\"", path);
GWEN_DB_Group_free(db);
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
return 0;
}

/* create context */
ctx=GWEN_IPCXMLSecCtx_new(localName, remoteName);
if (GWEN_SecContext_FromDB(ctx, db)) {
GWEN_SecContext_free(ctx);
DBG_ERROR(0, "Could not read context \"%s:%s\"from DB",
localName, remoteName);
GWEN_DB_Group_free(db);
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
return 0;
}
/* store lock id (which actually is the file descriptor) */
GWEN_SecContext_SetLockId(ctx, fid);

/* store local files if they are not already set */
if (GWEN_IPCXMLSecCtx_GetLocalSignKey(ctx)==0 &&
scmd->localSignKey)
GWEN_IPCXMLSecCtx_SetLocalSignKey(ctx,scmd->localSignKey);
if (GWEN_IPCXMLSecCtx_GetLocalCryptKey(ctx)==0 &&
scmd->localCryptKey)
GWEN_IPCXMLSecCtx_SetLocalCryptKey(ctx,scmd->localCryptKey);
/* done */
return ctx;
}
}
else {
GWEN_SECCTX *ctx;

/* create a local-only context */
DBG_INFO(0, "Creating local-only context");
ctx=GWEN_IPCXMLSecCtx_new(localName, remoteName);
if (scmd->localSignKey)
GWEN_IPCXMLSecCtx_SetLocalSignKey(ctx,scmd->localSignKey);
if (scmd->localCryptKey)
GWEN_IPCXMLSecCtx_SetLocalCryptKey(ctx,scmd->localCryptKey);
return ctx;
}
}



int GWEN_IPCXMLSecCtxMgr_AddContext(GWEN_SECCTX_MANAGER *scm,
GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXMGRDATA *scmd;
char path[256];
const char *localName;
const char *remoteName;
GWEN_DB_NODE *db;
int fid;
unsigned int flags;

assert(scm);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);

localName=GWEN_SecContext_GetLocalName(sc);
remoteName=GWEN_SecContext_GetRemoteName(sc);
flags=GWEN_SecContext_GetFlags(sc);

if (!remoteName) {
DBG_ERROR(0, "Will not add local-only context \"%s\"",
localName);
return -1;
}

/* check for the existence of a file for the context */
DBG_INFO(0, "Trying to read context \"%s:%s\"",
localName, remoteName);
if (strlen(scmd->dir)+
strlen(localName)+
strlen(remoteName)+
4>sizeof(path)) {
DBG_ERROR(0, "Path too long");
return 0;
}
strcpy(path, scmd->dir);
strcat(path, "/");
strcat(path, localName);
strcat(path, "/");
strcat(path, remoteName);
strcat(path, ".ctx");
if (GWEN_Directory_GetPath(path,
GWEN_PATH_FLAGS_VARIABLE |
GWEN_PATH_FLAGS_PATHMUSTEXIST)==0) {
DBG_ERROR(0, "Context \"%s:%s\" already exists, not adding it",
localName, remoteName);
return -1;
}

if (GWEN_IPCXMLSecCtxtMgr_FindContext(scm, localName, remoteName)) {
DBG_ERROR(0, "Context \"%s:%s\" already exists locally, not adding it",
localName, remoteName);
return -1;
}

if (flags & GWEN_SECCTX_FLAGS_TEMP) {
DBG_INFO(0, "Adding temporary context \"%s:%s\"",
localName, remoteName);
GWEN_List_PushBack(scmd->contextList, sc);
return 0;
}

fid=GWEN_IPCXMLSecCtxMgr_LockFile(path);
if (fid==-1) {
DBG_ERROR(0, "Could not lock context file for \"%s:%s\"",
localName, remoteName);
return -1;
}

db=GWEN_DB_Group_new("context");
if (GWEN_SecContext_ToDB(sc, db)) {
DBG_ERROR(0, "Could not write context \"%s:%s\" to DB",
localName, remoteName);
GWEN_DB_Group_free(db);
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
return -1;
}

if (GWEN_DB_WriteFile(db, path,
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_CREATE_GROUP)) {
DBG_ERROR(0, "Error writing file \"%s\"", path);
GWEN_DB_Group_free(db);
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
return -1;
}

GWEN_DB_Group_free(db);
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
GWEN_SecContext_free(sc);
return 0;
}



int GWEN_IPCXMLSecCtxMgr_DelContext(GWEN_SECCTX_MANAGER *scm,
GWEN_SECCTX *sc){
GWEN_IPCXMLSECCTXMGRDATA *scmd;
char path[256];
const char *localName;
const char *remoteName;

assert(scm);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);

localName=GWEN_SecContext_GetLocalName(sc);
remoteName=GWEN_SecContext_GetRemoteName(sc);

/* try to read the file */
DBG_INFO(0, "Trying to read context \"%s:%s\"",
localName, remoteName);
if (strlen(scmd->dir)+
strlen(localName)+
strlen(remoteName)+
4>sizeof(path)) {
DBG_ERROR(0, "Path too long");
return 0;
}
strcpy(path, scmd->dir);
strcat(path, "/");
strcat(path, localName);
strcat(path, "/");
strcat(path, remoteName);
strcat(path, ".ctx");
if (GWEN_Directory_GetPath(path,
GWEN_PATH_FLAGS_VARIABLE |
GWEN_PATH_FLAGS_PATHMUSTEXIST)==0) {
int fid;

fid=GWEN_SecContext_GetLockId(sc);

/* file exists, remove it */
DBG_INFO(0, "Removing file for context \"%s:%s\"",
localName, remoteName);
if (unlink(path)) {
DBG_ERROR(0, "Error on unlink(%s): %s",
path, strerror(errno));
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
return -1;
}
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
GWEN_SecContext_free(sc);
return 0;
}
else {
GWEN_LIST_ITERATOR *it;

/* remove temporary context */
it=GWEN_List_First(scmd->contextList);
if (it) {
GWEN_SECCTX *ctx;

ctx=(GWEN_SECCTX*)GWEN_ListIterator_Data(it);
while(ctx) {
if ((GWEN_Text_Compare(GWEN_SecContext_GetLocalName(ctx),
localName, 1)==0) &&
(GWEN_Text_Compare(GWEN_SecContext_GetRemoteName(ctx),
remoteName, 1)==0)){
GWEN_ListIterator_free(it);
GWEN_SecContext_free(ctx);
return 0;
}
ctx=(GWEN_SECCTX*)GWEN_ListIterator_Next(it);
} /* while */
}
GWEN_ListIterator_free(it);
DBG_INFO(0, "Context \"%s:%s\" not found",
localName, remoteName);
return -1;
}
}



int GWEN_IPCXMLSecCtxMgr_ReleaseContext(GWEN_SECCTX_MANAGER *scm,
GWEN_SECCTX *sc,
int aban){
GWEN_IPCXMLSECCTXMGRDATA *scmd;
char path[256];
const char *localName;
const char *remoteName;

assert(scm);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);

localName=GWEN_SecContext_GetLocalName(sc);
remoteName=GWEN_SecContext_GetRemoteName(sc);

if (!remoteName) {
DBG_INFO(0, "Releasing local context \"%s\"", localName);
GWEN_SecContext_free(sc);
return 0;
}

if (GWEN_SecContext_GetFlags(sc) & GWEN_SECCTX_FLAGS_TEMP) {
if (GWEN_IPCXMLSecCtxtMgr_FindContext(scm, localName, remoteName)==0) {
DBG_ERROR(0, "Context \"%s:%s\" not found",
localName, remoteName);
return -1;
}
GWEN_SecContext_free(sc);
return 0;
}
else {
/* try to write the file */
if (strlen(scmd->dir)+
strlen(localName)+
strlen(remoteName)+
4>sizeof(path)) {
DBG_ERROR(0, "Path too long");
return 0;
}
strcpy(path, scmd->dir);
strcat(path, "/");
strcat(path, localName);
strcat(path, "/");
strcat(path, remoteName);
strcat(path, ".ctx");
if (GWEN_Directory_GetPath(path,
GWEN_PATH_FLAGS_VARIABLE |
GWEN_PATH_FLAGS_PATHMUSTEXIST)==0) {
int fid;

fid=GWEN_SecContext_GetLockId(sc);

/* file exists, save it */
if (!aban) {
GWEN_DB_NODE *db;

/* only write file if not in abandon mode */
db=GWEN_DB_Group_new("context");
if (GWEN_SecContext_ToDB(sc, db)) {
DBG_ERROR(0, "Could not write context \"%s:%s\" to DB",
localName, remoteName);
GWEN_DB_Group_free(db);
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
return -1;
}

if (GWEN_DB_WriteFile(db, path,
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_CREATE_GROUP)) {
DBG_ERROR(0, "Error writing file \"%s\"", path);
GWEN_DB_Group_free(db);
GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
return -1;
}
} /* if not abandon */
else {
DBG_INFO(0, "Abandoning context \"%s:%s\"",
localName, remoteName);
}

GWEN_IPCXMLSecCtxMgr_UnlockFile(fid);
DBG_INFO(0, "Context \"%s:%s\" released",
localName, remoteName);
GWEN_SecContext_free(sc);
return 0;
}
else {
/* file does not exist */
DBG_ERROR(0, "Context \"%s:%s\" not found",
localName, remoteName);
return -1;
}
}
}



GWEN_IPCXMLSECCTXMGRDATA *GWEN_IPCXMLSecCtxMgrData_new() {
GWEN_IPCXMLSECCTXMGRDATA *scmd;

GWEN_NEW_OBJECT(GWEN_IPCXMLSECCTXMGRDATA, scmd);
scmd->contextList=GWEN_List_new();
return scmd;
};



void GWEN_IPCXMLSecCtxMgrData_free(GWEN_SECCTX_MANAGER *scm) {
if (scm) {
GWEN_IPCXMLSECCTXMGRDATA *scmd;
GWEN_LIST_ITERATOR *it;

scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);

free(scmd->dir);
GWEN_CryptKey_free(scmd->localSignKey);
GWEN_CryptKey_free(scmd->localCryptKey);

/* free all temporary contexts */
it=GWEN_List_First(scmd->contextList);
if (it) {
GWEN_SECCTX *sc;

sc=(GWEN_SECCTX*)GWEN_ListIterator_Data(it);
while(sc) {
GWEN_SecContext_free(sc);
sc=(GWEN_SECCTX*)GWEN_ListIterator_Next(it);
} /* while */
GWEN_ListIterator_free(it);
}
GWEN_List_free(scmd->contextList);
} /* if scm */
}



GWEN_SECCTX_MANAGER *GWEN_IPCXMLSecCtxMgr_new(const char *serviceCode,
const char *dir){
GWEN_SECCTX_MANAGER *scm;
GWEN_IPCXMLSECCTXMGRDATA *scmd;

assert(serviceCode);
assert(dir);

scm=GWEN_SecContextMgr_new(serviceCode);
scmd=GWEN_IPCXMLSecCtxMgrData_new();
GWEN_SecContextMgr_SetData(scm, scmd);
scmd->dir=strdup(dir);

GWEN_SecContextMgr_SetGetFn(scm, GWEN_IPCXMLSecCtxMgr_GetContext);
GWEN_SecContextMgr_SetAddFn(scm, GWEN_IPCXMLSecCtxMgr_AddContext);
GWEN_SecContextMgr_SetDelFn(scm, GWEN_IPCXMLSecCtxMgr_DelContext);
GWEN_SecContextMgr_SetReleaseFn(scm, GWEN_IPCXMLSecCtxMgr_ReleaseContext);
GWEN_SecContextMgr_SetFreeDataFn(scm, GWEN_IPCXMLSecCtxMgrData_free);

return scm;
}



void GWEN_IPCXMLSecCtxMgr_SetLocalSignKey(GWEN_SECCTX_MANAGER *scm,
const GWEN_CRYPTKEY *key){
GWEN_IPCXMLSECCTXMGRDATA *scmd;

assert(scm);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);

assert(key);
if (scmd->localSignKey)
GWEN_CryptKey_free(scmd->localSignKey);
scmd->localSignKey=GWEN_CryptKey_dup(key);
}



void GWEN_IPCXMLSecCtxMgr_SetLocalCryptKey(GWEN_SECCTX_MANAGER *scm,
const GWEN_CRYPTKEY *key){
GWEN_IPCXMLSECCTXMGRDATA *scmd;

assert(scm);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);

assert(key);
if (scmd->localCryptKey)
GWEN_CryptKey_free(scmd->localCryptKey);
scmd->localCryptKey=GWEN_CryptKey_dup(key);
}



const GWEN_CRYPTKEY*
GWEN_IPCXMLSecCtxMgr_GetLocalSignKey(GWEN_SECCTX_MANAGER *scm){
GWEN_IPCXMLSECCTXMGRDATA *scmd;

assert(scm);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);

return scmd->localSignKey;
}



const GWEN_CRYPTKEY*
GWEN_IPCXMLSecCtxMgr_GetLocalCryptKey(GWEN_SECCTX_MANAGER *scm){
GWEN_IPCXMLSECCTXMGRDATA *scmd;

assert(scm);
scmd=(GWEN_IPCXMLSECCTXMGRDATA*)GWEN_SecContextMgr_GetData(scm);
assert(scmd);

return scmd->localCryptKey;
}








(17-17/19)