Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 52ba1d9b

Von aquamaniac vor mehr als 19 Jahren hinzugefügt

  • ID 52ba1d9b5a5a6008b1530cdc400f8a9c5265780a
  • Vorgänger 69c1f2a3
  • Nachfolger 6bbb87f8

- added function GWEN_NetLayer_WaitForStatus()
- fixed two bugs in PKCS1 padding
- finally fixed the spurious signature bug which sometimes caused HBCI
signatures to be invalid

git-svn-id: https://devel.aqbanking.de/svn/gwenhywfar/trunk@985 70169cfe-8b10-0410-8925-dcb4b91034d8

Unterschiede anzeigen:

ChangeLog
! as soon as the next release of GnuCash is out (2.0.0) !
------------------------------------------------------------------------
-------------- REMINDER PLEASE KEEP ON TOP UNTIL RELEASE----------------
! remember to do SO_CURRENT++ and SO_AGE++ before next release !
------------------------------------------------------------------------
2006/02/10: Martin Preuss<martin@libchipcard.de>
-------------------------------------------------
- finally fixed the spurious signature bug which sometimes caused HBCI
signatures to be invalid
2006/02/09: Martin Preuss<martin@libchipcard.de>
-------------------------------------------------
- added function GWEN_NetLayer_WaitForStatus()
- fixed two bugs in PKCS1 padding
2006/02/07: Martin Preuss<martin@libchipcard.de>
-------------------------------------------------
- declare GWEN_Random() public
===========================================================================
configure.ac
GWENHYWFAR_VERSION_MAJOR=1
GWENHYWFAR_VERSION_MINOR=99
GWENHYWFAR_VERSION_PATCHLEVEL=7
GWENHYWFAR_VERSION_BUILD=0
GWENHYWFAR_VERSION_BUILD=1
dnl "stable", "rcX", "betaX", "cvs"
GWENHYWFAR_VERSION_TAG="stable"
GWENHYWFAR_VERSION_TAG="cvs"
GWENHYWFAR_VERSION_FULL_STRING="$GWENHYWFAR_VERSION_MAJOR.$GWENHYWFAR_VERSION_MINOR.$GWENHYWFAR_VERSION_PATCHLEVEL.$GWENHYWFAR_VERSION_BUILD${GWENHYWFAR_VERSION_TAG}"
GWENHYWFAR_VERSION_STRING="$GWENHYWFAR_VERSION_MAJOR.$GWENHYWFAR_VERSION_MINOR.$GWENHYWFAR_VERSION_PATCHLEVEL"
src/crypt/crypt.h
void GWEN_Crypt_UnregisterAllProviders();
GWENHYWFAR_API
long int GWEN_Random();
#ifdef __cplusplus
}
#endif
src/crypt/crypt_l.h
GWENHYWFAR_API
GWEN_ERRORCODE GWEN_Crypt_ModuleFini();
GWENHYWFAR_API
long int GWEN_Random();
/** @name Functions expected in implementation
*
src/crypt/ossl/cryptssl.c
#include "cryptssl_p.h"
#include "cryptssl_bf_p.h"
#include "cryptssl_des_p.h"
#include "cryptssl_rsa_p.h"
#include "cryptssl_md5_p.h"
#include "cryptssl_sha1_p.h"
#include "cryptssl_rmd160_p.h"
#include <gwenhywfar/misc.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/text.h>
src/crypt/ossl/cryptssl_bf_p.h
#include <openssl/objects.h>
GWEN_ERRORCODE GWEN_CryptKeyBF_Register();
GWEN_CRYPTKEY *GWEN_CryptKeyBF_new();
GWEN_CRYPTKEY *GWEN_CryptKeyBF_dup(const GWEN_CRYPTKEY *key);
void GWEN_CryptKeyBF_FreeKeyData(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyBF_Encrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyBF_Decrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyBF_Sign(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyBF_Verify(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *signature);
unsigned int GWEN_CryptKeyBF_GetChunkSize(const GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyBF_FromDb(GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db);
GWEN_ERRORCODE GWEN_CryptKeyBF_ToDb(const GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db,
int pub);
GWEN_ERRORCODE GWEN_CryptKeyBF_Generate(GWEN_CRYPTKEY *key,
unsigned keylength);
GWEN_ERRORCODE GWEN_CryptKeyBF_Open(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyBF_Close(GWEN_CRYPTKEY *key);
static GWEN_CRYPTKEY *GWEN_CryptKeyBF_new();
static GWEN_CRYPTKEY *GWEN_CryptKeyBF_dup(const GWEN_CRYPTKEY *key);
static void GWEN_CryptKeyBF_FreeKeyData(GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyBF_Encrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyBF_Decrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyBF_Sign(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyBF_Verify(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *signature);
static unsigned int GWEN_CryptKeyBF_GetChunkSize(const GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyBF_FromDb(GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db);
static GWEN_ERRORCODE GWEN_CryptKeyBF_ToDb(const GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db,
int pub);
static GWEN_ERRORCODE GWEN_CryptKeyBF_Generate(GWEN_CRYPTKEY *key,
unsigned keylength);
static GWEN_ERRORCODE GWEN_CryptKeyBF_Open(GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyBF_Close(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyBF_Crypt(const GWEN_CRYPTKEY *key,
src/crypt/ossl/cryptssl_des_p.h
#include <openssl/objects.h>
GWEN_ERRORCODE GWEN_CryptKeyDES_Register();
GWEN_CRYPTKEY *GWEN_CryptKeyDES_new();
GWEN_CRYPTKEY *GWEN_CryptKeyDES_dup(const GWEN_CRYPTKEY *key);
void GWEN_CryptKeyDES_FreeKeyData(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyDES_Encrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyDES_Decrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyDES_Sign(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyDES_Verify(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *signature);
unsigned int GWEN_CryptKeyDES_GetChunkSize(const GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyDES_FromDb(GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db);
GWEN_ERRORCODE GWEN_CryptKeyDES_ToDb(const GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db,
int pub);
GWEN_ERRORCODE GWEN_CryptKeyDES_Generate(GWEN_CRYPTKEY *key,
unsigned keylength);
GWEN_ERRORCODE GWEN_CryptKeyDES_Open(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyDES_Close(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyDES_Crypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst,
int cryptMode);
static GWEN_CRYPTKEY *GWEN_CryptKeyDES_new();
static GWEN_CRYPTKEY *GWEN_CryptKeyDES_dup(const GWEN_CRYPTKEY *key);
static void GWEN_CryptKeyDES_FreeKeyData(GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Encrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Decrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Sign(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Verify(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *signature);
static unsigned int GWEN_CryptKeyDES_GetChunkSize(const GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyDES_FromDb(GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db);
static GWEN_ERRORCODE GWEN_CryptKeyDES_ToDb(const GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db,
int pub);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Generate(GWEN_CRYPTKEY *key,
unsigned keylength);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Open(GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Close(GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyDES_Crypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst,
int cryptMode);
src/crypt/ossl/cryptssl_l.h
void GWEN_CryptImpl_Dump_Bignum(BIGNUM *bn, FILE *f, int indent);
GWEN_ERRORCODE GWEN_CryptKeyBF_Register();
GWEN_ERRORCODE GWEN_CryptKeyDES_Register();
GWEN_ERRORCODE GWEN_MdMd5_Register();
GWEN_ERRORCODE GWEN_MdRmd160_Register();
GWEN_ERRORCODE GWEN_MdSha1_Register();
GWEN_ERRORCODE GWEN_CryptKeyRSA_Register();
#endif
src/crypt/ossl/cryptssl_md5_p.h
#include <openssl/objects.h>
GWEN_ERRORCODE GWEN_MdMd5_Register();
GWEN_MD *GWEN_MdMd5_new();
void GWEN_MdMd5_FreeData(GWEN_MD *md);
int GWEN_MdMd5_Begin(GWEN_MD *md);
int GWEN_MdMd5_End(GWEN_MD *md);
int GWEN_MdMd5_Update(GWEN_MD *md,
const char *buf,
unsigned int l);
static GWEN_MD *GWEN_MdMd5_new();
static void GWEN_MdMd5_FreeData(GWEN_MD *md);
static int GWEN_MdMd5_Begin(GWEN_MD *md);
static int GWEN_MdMd5_End(GWEN_MD *md);
static int GWEN_MdMd5_Update(GWEN_MD *md,
const char *buf,
unsigned int l);
src/crypt/ossl/cryptssl_rmd160_p.h
#include <openssl/objects.h>
GWEN_ERRORCODE GWEN_MdRmd160_Register();
GWEN_MD *GWEN_MdRmd160_new();
void GWEN_MdRmd160_FreeData(GWEN_MD *md);
int GWEN_MdRmd160_Begin(GWEN_MD *md);
int GWEN_MdRmd160_End(GWEN_MD *md);
int GWEN_MdRmd160_Update(GWEN_MD *md,
const char *buf,
unsigned int l);
static GWEN_MD *GWEN_MdRmd160_new();
static void GWEN_MdRmd160_FreeData(GWEN_MD *md);
static int GWEN_MdRmd160_Begin(GWEN_MD *md);
static int GWEN_MdRmd160_End(GWEN_MD *md);
static int GWEN_MdRmd160_Update(GWEN_MD *md,
const char *buf,
unsigned int l);
src/crypt/ossl/cryptssl_rsa.c
GWEN_ERRORCODE GWEN_CryptKeyRSA_SignBigNum(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
BIGNUM *bnresult){
unsigned int srclen;
unsigned char *psrc;
RSA *kd;
int res;
BIGNUM *bnhash;
BIGNUM *bnresult2;
BN_CTX *bnctx;
assert(key);
assert(src);
assert(bnresult);
kd=(RSA*)GWEN_CryptKey_GetKeyData(key);
assert(kd);
srclen=GWEN_Buffer_GetUsedBytes(src);
if (srclen!=GWEN_CryptKey_GetChunkSize(key)) {
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
GWEN_Error_FindType(GWEN_CRYPT_ERROR_TYPE),
GWEN_CRYPT_ERROR_BAD_SIZE);
}
psrc=(unsigned char*)GWEN_Buffer_GetStart(src);
bnhash = BN_new();
bnresult2 = BN_new();
bnctx = BN_CTX_new();
bnhash = BN_bin2bn(psrc, srclen, bnhash);
BN_CTX_start(bnctx);
res=BN_mod_exp(bnresult, bnhash, kd->d, kd->n, bnctx);
/* the iso9796-appendix is as follows:
* if (the calculated signature - the modulus) < (the calculated signature)
* use (the calculated signature - the modulus) as signature
*/
if (BN_cmp(bnresult, kd->n) < 0) {
if (!BN_sub(bnresult2, kd->n, bnresult)) {
DBG_ERROR(GWEN_LOGDOMAIN, "Math error");
BN_free(bnresult2);
BN_free(bnhash);
return -1;
}
if (BN_cmp(bnresult2, bnresult) < 0) {
DBG_DEBUG(GWEN_LOGDOMAIN, "Using smaller signature");
BN_copy(bnresult, bnresult2);
}
}
BN_free(bnresult2);
BN_free(bnhash);
return 0;
}
GWEN_ERRORCODE GWEN_CryptKeyRSA_Sign(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst){
unsigned int srclen;
unsigned char *pdst;
unsigned char *psrc;
int firstPos;
RSA *kd;
BIGNUM *bnresult;
int res;
BIGNUM *bnhash;
BIGNUM *bnresult2;
BN_CTX *bnctx;
BIGNUM *bnresult1;
BIGNUM *bnresult2;
BIGNUM *bnSignature;
BIGNUM *bnhash;
int res;
assert(key);
assert(src);
......
kd=(RSA*)GWEN_CryptKey_GetKeyData(key);
assert(kd);
firstPos=GWEN_Buffer_GetPos(dst);
bnctx=BN_CTX_new();
BN_CTX_start(bnctx);
bnhash=BN_CTX_get(bnctx);
bnresult1=BN_CTX_get(bnctx);
bnresult2=BN_CTX_get(bnctx);
srclen=GWEN_Buffer_GetUsedBytes(src);
if (srclen!=GWEN_CryptKey_GetChunkSize(key)) {
DBG_INFO(GWEN_LOGDOMAIN, "Bad size of source data (%d!=%d)",
srclen, GWEN_CryptKey_GetChunkSize(key));
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
GWEN_Error_FindType(GWEN_CRYPT_ERROR_TYPE),
......
}
if (GWEN_Buffer_AllocRoom(dst, srclen)) {
DBG_INFO(GWEN_LOGDOMAIN, "Could not allocate room for %d bytes", srclen);
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
GWEN_Error_FindType(GWEN_CRYPT_ERROR_TYPE),
GWEN_CRYPT_ERROR_BUFFER_FULL);
}
bnresult = BN_new();
/* sign the src */
psrc=(unsigned char*)GWEN_Buffer_GetStart(src);
bnhash = BN_new();
bnresult2 = BN_new();
bnctx = BN_CTX_new();
bnhash=BN_bin2bn(psrc, srclen, bnhash);
/* result1=(hash^privateExponent) % modulus */
res=BN_mod_exp(bnresult1, bnhash, kd->d, kd->n, bnctx);
bnhash = BN_bin2bn(psrc, srclen, bnhash);
BN_CTX_start(bnctx);
res=BN_mod_exp(bnresult, bnhash, kd->d, kd->n, bnctx);
/* FIXME: The description is quite the opposite of the code, while the
* code seems to be working (at least when verifying my own signatures)
* the iso9796-appendix is as follows:
* if ((the calculated signature - the modulus) <
/* the iso9796-appendix is as follows:
* if ((the modulus - the calculated signature) <
* (the calculated signature))
* then use (the calculated signature - the modulus) as signature
* then use (the modulus - the calculated signature) as signature
*/
if (!BN_sub(bnresult2, kd->n, bnresult)) {
/* result2=modulus-result1 */
if (!BN_sub(bnresult2, kd->n, bnresult1)) {
DBG_ERROR(GWEN_LOGDOMAIN, "Math error");
BN_free(bnresult2);
BN_free(bnhash);
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
GWEN_Error_FindType(GWEN_CRYPT_ERROR_TYPE),
GWEN_CRYPT_ERROR_SIGN);
}
bnSignature=bnresult1;
if (!(GWEN_CryptKey_GetFlags(key) &
GWEN_CRYPT_FLAG_DISABLE_SMALLER_SIGNATURE)) {
if (BN_cmp(bnresult2, bnresult) < 0) {
if (BN_cmp(bnresult2, bnresult1) < 0) {
/* GWEN_WaitCallback_Log(0, "Using smaller signature"); */
DBG_DEBUG(GWEN_LOGDOMAIN, "Using smaller signature");
BN_copy(bnresult, bnresult2);
DBG_INFO(GWEN_LOGDOMAIN, "Using smaller signature");
bnSignature=bnresult2;
}
else {
/* GWEN_WaitCallback_Log(0, "Using normal signature"); */
......
/* GWEN_WaitCallback_Log(0, "Always using normal signature"); */
}
BN_free(bnresult2);
BN_free(bnhash);
if (GWEN_Buffer_GetPos(dst)!=0) {
DBG_WARN(GWEN_LOGDOMAIN, "Not at start pos, we could otherwise be much faster");
DBG_WARN(GWEN_LOGDOMAIN,
"Not at start pos, we could otherwise be much faster");
}
/* padd up to srclen */
pdst=(unsigned char*)GWEN_Buffer_GetPosPointer(dst);
res=BN_bn2bin(bnresult, pdst);
res=BN_bn2bin(bnSignature, pdst);
GWEN_Buffer_IncrementPos(dst, res);
GWEN_Buffer_AdjustUsedBytes(dst);
if ((unsigned int)res<srclen) {
GWEN_Buffer_SetPos(dst, firstPos);
/* padd to multiple of 8 bytes */
if (res % 8) {
unsigned int j;
unsigned int k;
if (GWEN_Buffer_ReserveBytes(dst, srclen-res)) {
DBG_INFO(GWEN_LOGDOMAIN, "Could not reserve %d bytes", srclen-res);
j=8-((unsigned int)res%8);
if (GWEN_Buffer_ReserveBytes(dst, j)) {
DBG_INFO(GWEN_LOGDOMAIN, "Could not reserve %d bytes", j);
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
GWEN_Error_FindType(GWEN_CRYPT_ERROR_TYPE),
GWEN_CRYPT_ERROR_BUFFER_FULL);
}
for (j=0; j<(srclen-res); j++) {
for (k=0; k<j; k++) {
GWEN_Buffer_InsertByte(dst, 0);
}
}
pdst=(unsigned char*)GWEN_Buffer_GetPosPointer(dst);
BN_free(bnresult);
GWEN_Buffer_IncrementPos(dst, srclen);
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return 0;
}
......
unsigned char *psrc;
unsigned char *psig;
RSA *kd;
BIGNUM *bnsig;
BIGNUM *bndecsig;
BIGNUM *bnhash;
BN_CTX *bnctx;
BIGNUM *bnsig1;
BIGNUM *bnsig2;
BIGNUM *bndecsig1;
BIGNUM *bndecsig2;
BIGNUM *bnhash;
assert(key);
assert(src);
......
kd=(RSA*)GWEN_CryptKey_GetKeyData(key);
assert(kd);
bnctx=BN_CTX_new();
BN_CTX_start(bnctx);
bnsig1=BN_CTX_get(bnctx);
bnsig2=BN_CTX_get(bnctx);
bndecsig1=BN_CTX_get(bnctx);
bndecsig2=BN_CTX_get(bnctx);
bnhash=BN_CTX_get(bnctx);
srclen=GWEN_Buffer_GetUsedBytes(src);
psrc=(unsigned char*)GWEN_Buffer_GetStart(src);
siglen=GWEN_Buffer_GetUsedBytes(signature);
psig=(unsigned char*)GWEN_Buffer_GetStart(signature);
bnsig=BN_new();
bndecsig=BN_new();
bnhash=BN_new();
bnctx=BN_CTX_new();
/* decrypt the institutes signature */
bnsig = BN_bin2bn(psig, siglen, bnsig);
BN_CTX_start(bnctx);
BN_mod_exp(bndecsig, bnsig, kd->e, kd->n, bnctx);
bnsig1=BN_bin2bn(psig, siglen, bnsig1);
BN_sub(bnsig2, kd->n, bnsig1);
bnhash=BN_bin2bn(psrc, srclen, bnhash);
bnhash = BN_bin2bn(psrc, srclen, bnhash);
BN_mod_exp(bndecsig1, bnsig1, kd->e, kd->n, bnctx);
BN_mod_exp(bndecsig2, bnsig2, kd->e, kd->n, bnctx);
if (BN_cmp(bndecsig, bnhash)!=0) {
if (BN_cmp(bndecsig1, bnhash)!=0) {
DBG_INFO(GWEN_LOGDOMAIN, "Trying other signature variant");
BN_sub(bnhash, kd->n, bnhash);
if (BN_cmp(bndecsig, bnhash)!=0) {
if (BN_cmp(bndecsig2, bnhash)!=0) {
DBG_ERROR(GWEN_LOGDOMAIN, "Signature does not match");
BN_free(bnsig);
BN_free(bndecsig);
BN_free(bnhash);
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return GWEN_Error_new(0,
GWEN_ERROR_SEVERITY_ERR,
......
}
}
BN_free(bnsig);
BN_free(bndecsig);
BN_free(bnhash);
BN_CTX_end(bnctx);
BN_CTX_free(bnctx);
return 0;
......
unsigned int len;
RSA *kd;
BIGNUM *bn;
int keylen;
kd=RSA_new();
assert(kd);
......
GWEN_DB_Dump(db, stderr, 2);
/* needed because older versions of GWEN did not store the keylength */
if (GWEN_CryptKey_GetKeyLength(key)==0)
GWEN_CryptKey_SetKeyLength(key, 768);
keylen=GWEN_CryptKey_GetKeyLength(key);
if (keylen==0) {
keylen=768;
GWEN_CryptKey_SetKeyLength(key, keylen);
}
pub=GWEN_DB_GetIntValue(db, "public", 0, 1);
GWEN_CryptKey_SetPublic(key, pub);
src/crypt/ossl/cryptssl_rsa_p.h
#include <openssl/objects.h>
GWEN_ERRORCODE GWEN_CryptKeyRSA_Register();
GWEN_CRYPTKEY *GWEN_CryptKeyRSA_new();
GWEN_CRYPTKEY *GWEN_CryptKeyRSA_dup(const GWEN_CRYPTKEY *key);
void GWEN_CryptKeyRSA_FreeKeyData(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyRSA_Encrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyRSA_Decrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyRSA_Sign(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
GWEN_ERRORCODE GWEN_CryptKeyRSA_Verify(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *signature);
unsigned int GWEN_CryptKeyRSA_GetChunkSize(const GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyRSA_FromDb(GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db);
GWEN_ERRORCODE GWEN_CryptKeyRSA_ToDb(const GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db,
int pub);
GWEN_ERRORCODE GWEN_CryptKeyRSA_Generate(GWEN_CRYPTKEY *key,
unsigned keylength);
GWEN_ERRORCODE GWEN_CryptKeyRSA_Open(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyRSA_Close(GWEN_CRYPTKEY *key);
GWEN_ERRORCODE GWEN_CryptKeyRSA_SignBigNum(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
BIGNUM *bnresult);
void GWEN_CryptKeyRSA_DumpPubKey(const GWEN_CRYPTKEY *key);
static GWEN_CRYPTKEY *GWEN_CryptKeyRSA_new();
static GWEN_CRYPTKEY *GWEN_CryptKeyRSA_dup(const GWEN_CRYPTKEY *key);
static void GWEN_CryptKeyRSA_FreeKeyData(GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_Encrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_Decrypt(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_Sign(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *dst);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_Verify(const GWEN_CRYPTKEY *key,
GWEN_BUFFER *src,
GWEN_BUFFER *signature);
static unsigned int GWEN_CryptKeyRSA_GetChunkSize(const GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_FromDb(GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_ToDb(const GWEN_CRYPTKEY *key,
GWEN_DB_NODE *db,
int pub);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_Generate(GWEN_CRYPTKEY *key,
unsigned keylength);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_Open(GWEN_CRYPTKEY *key);
static GWEN_ERRORCODE GWEN_CryptKeyRSA_Close(GWEN_CRYPTKEY *key);
static void GWEN_CryptKeyRSA_DumpPubKey(const GWEN_CRYPTKEY *key);
#endif
src/crypt/ossl/cryptssl_sha1_p.h
#include <openssl/objects.h>
GWEN_ERRORCODE GWEN_MdSha1_Register();
GWEN_MD *GWEN_MdSha1_new();
void GWEN_MdSha1_FreeData(GWEN_MD *md);
int GWEN_MdSha1_Begin(GWEN_MD *md);
int GWEN_MdSha1_End(GWEN_MD *md);
int GWEN_MdSha1_Update(GWEN_MD *md,
const char *buf,
unsigned int l);
static GWEN_MD *GWEN_MdSha1_new();
static void GWEN_MdSha1_FreeData(GWEN_MD *md);
static int GWEN_MdSha1_Begin(GWEN_MD *md);
static int GWEN_MdSha1_End(GWEN_MD *md);
static int GWEN_MdSha1_Update(GWEN_MD *md,
const char *buf,
unsigned int l);
src/crypt/padd.c
p=GWEN_Buffer_GetStart(buf);
*(p++)=0x00;
*(p++)=0x01; /* block type 01 */
if (diff>11) {
memset(p, 0xff, diff-11);
p+=diff-11;
if (diff>3) {
memset(p, 0xff, diff-3);
p+=diff-3;
}
*(p++)=0x00;
......
p=GWEN_Buffer_GetStart(buf);
*(p++)=0x00;
*(p++)=0x02; /* block type 02 */
for (i=0; i<diff-11; i++) {
for (i=0; i<diff-3; i++) {
int r;
while( (r=GWEN_Random() & 0xff) == 0 );
src/crypt2/ct_file.c
ki=GWEN_CryptToken_Context_GetSignKeyInfo(ctx);
assert(ki);
kid=GWEN_CryptToken_KeyInfo_GetKeyId(ki);
if ((kid & 0xf)!=1) {
DBG_ERROR(GWEN_LOGDOMAIN, "Invalid key id");
if ((!auth && (kid & 0xf)!=1) ||
(auth && (kid & 0xf)!=5)) {
DBG_ERROR(GWEN_LOGDOMAIN, "Invalid key id \%02x\"", kid);
return GWEN_ERROR_INVALID;
}
if (!(GWEN_CryptToken_KeyInfo_GetKeyFlags(ki) &
src/net2/netlayer.c
/* -------------------------------------------------------------- FUNCTION */
int GWEN_NetLayer_WaitForStatus(GWEN_NETLAYER *nl,
GWEN_NETLAYER_STATUS nlst,
int timeout) {
time_t startt;
int distance;
int count;
assert(nl);
startt=time(0);
if (timeout==GWEN_NET2_TIMEOUT_NONE)
distance=GWEN_NET2_TIMEOUT_NONE;
else if (timeout==GWEN_NET2_TIMEOUT_FOREVER)
distance=GWEN_NET2_TIMEOUT_FOREVER;
else {
distance=GWEN_WaitCallback_GetDistance(0);
if (distance)
if ((distance)>timeout)
distance=timeout;
if (!distance)
distance=750;
}
for (count=0;;count++) {
GWEN_NETLAYER_STATUS st;
GWEN_NETLAYER_RESULT res;
double d;
if (GWEN_WaitCallback()==GWEN_WaitCallbackResult_Abort) {
DBG_INFO(GWEN_LOGDOMAIN, "User aborted");
return GWEN_ERROR_USER_ABORTED;
}
st=GWEN_NetLayer_GetStatus(nl);
if (st==nlst)
return 0;
if (st!=GWEN_NetLayerStatus_Connecting &&
st!=GWEN_NetLayerStatus_Disconnecting) {
DBG_ERROR(GWEN_LOGDOMAIN, "Bad status of netlayer: %s",
GWEN_NetLayerStatus_toString(st));
return GWEN_ERROR_GENERIC;
}
res=GWEN_Net_HeartBeat(distance);
if (res==GWEN_NetLayerResult_Error) {
DBG_INFO(GWEN_LOGDOMAIN, "here");
return GWEN_ERROR_GENERIC;
}
d=difftime(time(0), startt);
/* check timeout */
if (timeout!=GWEN_NET2_TIMEOUT_FOREVER) {
if (timeout==GWEN_NET2_TIMEOUT_NONE ||
d>timeout) {
DBG_INFO(GWEN_LOGDOMAIN,
"Timeout (%d) while waiting, giving up",
timeout);
return 1;
}
}
if (count && d) {
int ratio;
ratio=count/d;
if (ratio>100) {
/* insert sleep cycle to avoid CPU overuse which could prevent
* the user from aborting a program running wild */
DBG_WARN(GWEN_LOGDOMAIN,
"WARNING: Inserting sleep cycle, "
"please check the code! (%d)", ratio);
GWEN_Socket_Select(0, 0, 0, 750);
}
}
} /* for */
}
/* -------------------------------------------------------------- FUNCTION */
int GWEN_NetLayer_Connect(GWEN_NETLAYER *nl) {
assert(nl);
src/net2/netlayer.h
const char *buffer, int *bsize,
int timeout);
GWENHYWFAR_API
int GWEN_NetLayer_WaitForStatus(GWEN_NETLAYER *nl,
GWEN_NETLAYER_STATUS nlst,
int timeout);
GWENHYWFAR_API
int GWEN_NetLayer_Connect(GWEN_NETLAYER *nl);
src/testlib.c
#include <gwenhywfar/buffer.h>
#include <gwenhywfar/base64.h>
#include <gwenhywfar/crypt.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/md.h>
#include <gwenhywfar/padd.h>
......
int i;
int len;
fprintf(stderr, "Check 1 ...");
buf1=GWEN_Buffer_new(0, 256, 0, 1);
rv=GWEN_Base64_Encode((const unsigned char*)testString,
strlen(testString),
......
return 3;
}
fprintf(stderr, "Check 1: PASSED.\n");
fprintf(stderr, "PASSED.\n");
return 0;
}
int _check2() {
const char *testString="This is a little test string";
int rv;
GWEN_BUFFER *buf1;
GWEN_BUFFER *buf2;
GWEN_CRYPTKEY *key;
GWEN_CRYPTKEY *pubKey;
GWEN_CRYPTKEY *privKey;
GWEN_ERRORCODE err;
GWEN_DB_NODE *dbPubKey;
GWEN_DB_NODE *dbPrivKey;
key=GWEN_CryptKey_Factory("RSA");
if (!key) {
fprintf(stderr, "FAILED: Could not create RSA key.\n");
return 2;
}
err=GWEN_CryptKey_Generate(key, 1024);
if (!GWEN_Error_IsOk(err)) {
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not generate key.\n");
return 2;
}
/* private key */
dbPrivKey=GWEN_DB_Group_new("privkey");
err=GWEN_CryptKey_toDb(key, dbPrivKey, 0);
if (!GWEN_Error_IsOk(err)) {
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not extract private key.\n");
return 2;
}
privKey=GWEN_CryptKey_fromDb(dbPrivKey);
if (privKey==0) {
fprintf(stderr, "FAILED: Could not create private key.\n");
return 2;
}
/* public key */
dbPubKey=GWEN_DB_Group_new("pubkey");
err=GWEN_CryptKey_toDb(key, dbPubKey, 1);
if (!GWEN_Error_IsOk(err)) {
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not extract public key.\n");
return 2;
}
pubKey=GWEN_CryptKey_fromDb(dbPubKey);
if (pubKey==0) {
fprintf(stderr, "FAILED: Could not create public key.\n");
return 2;
}
/* hash */
buf1=GWEN_Buffer_new(0, 256, 0, 1);
rv=GWEN_MD_HashToBuffer("SHA1", testString, strlen(testString), buf1);
if (rv) {
fprintf(stderr, "FAILED: Could not hash data.\n");
return 2;
}
/* padd */
rv=GWEN_Padd_PaddWithPkcs1Bt1(buf1, 128);
if (rv) {
fprintf(stderr, "FAILED: Could not padd data.\n");
return 2;
}
/* sign */
buf2=GWEN_Buffer_new(0, 256, 0, 1);
err=GWEN_CryptKey_Sign(privKey, buf1, buf2);
if (!GWEN_Error_IsOk(err)) {
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not sign hash.\n");
return 2;
}
/* hash */
GWEN_Buffer_Reset(buf1);
buf1=GWEN_Buffer_new(0, 256, 0, 1);
rv=GWEN_MD_HashToBuffer("SHA1", testString, strlen(testString), buf1);
if (rv) {
fprintf(stderr, "FAILED: Could not hash data.\n");
return 2;
}
/* padd */
rv=GWEN_Padd_PaddWithPkcs1Bt1(buf1, 128);
if (rv) {
fprintf(stderr, "FAILED: Could not padd data.\n");
return 2;
}
/* verify */
err=GWEN_CryptKey_Verify(pubKey, buf1, buf2);
if (!GWEN_Error_IsOk(err)) {
GWEN_DB_NODE *dbKeys;
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not verify hash.\n");
dbKeys=GWEN_DB_Group_new("keys");
GWEN_DB_AddGroup(dbKeys, GWEN_DB_Group_dup(dbPrivKey));
GWEN_DB_AddGroup(dbKeys, GWEN_DB_Group_dup(dbPubKey));
GWEN_DB_SetBinValue(dbKeys, GWEN_DB_FLAGS_OVERWRITE_VARS,
"signature",
GWEN_Buffer_GetStart(buf2),
GWEN_Buffer_GetUsedBytes(buf2));
GWEN_DB_SetBinValue(dbKeys, GWEN_DB_FLAGS_OVERWRITE_VARS,
"hash",
GWEN_Buffer_GetStart(buf1),
GWEN_Buffer_GetUsedBytes(buf1));
GWEN_DB_WriteFile(dbKeys, "check2_failed_key",
GWEN_DB_FLAGS_DEFAULT);
GWEN_DB_Group_free(dbKeys);
return 2;
}
return 0;
}
int check2() {
int i;
fprintf(stderr, "Check 2 ...");
for (i=0; i<500; i++) {
int rv;
fprintf(stderr, ".");
rv=_check2();
if (rv)
return rv;
}
fprintf(stderr, "PASSED.\n");
return 0;
}
int test1() {
const char *testString="This is a little test string";
int rv;
GWEN_BUFFER *buf1;
GWEN_BUFFER *buf2;
GWEN_CRYPTKEY *key;
GWEN_CRYPTKEY *pubKey;
GWEN_CRYPTKEY *privKey;
GWEN_ERRORCODE err;
GWEN_DB_NODE *dbKeys;
GWEN_DB_NODE *dbPubKey;
GWEN_DB_NODE *dbPrivKey;
key=GWEN_CryptKey_Factory("RSA");
if (!key) {
fprintf(stderr, "FAILED: Could not create RSA key.\n");
return 2;
}
err=GWEN_CryptKey_Generate(key, 1024);
if (!GWEN_Error_IsOk(err)) {
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not generate key.\n");
return 2;
}
dbKeys=GWEN_DB_Group_new("keys");
if (GWEN_DB_ReadFile(dbKeys, "check2_failed_key",
GWEN_DB_FLAGS_DEFAULT |
GWEN_PATH_FLAGS_CREATE_GROUP)) {
fprintf(stderr, "FAILED: Could not load file.\n");
return 2;
}
/* private key */
dbPrivKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
"privkey");
assert(dbPrivKey);
privKey=GWEN_CryptKey_fromDb(dbPrivKey);
assert(privKey);
/* public key */
dbPubKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
"pubkey");
assert(dbPubKey);
pubKey=GWEN_CryptKey_fromDb(dbPubKey);
assert(pubKey);
/* hash */
buf1=GWEN_Buffer_new(0, 256, 0, 1);
rv=GWEN_MD_HashToBuffer("SHA1", testString, strlen(testString), buf1);
if (rv) {
fprintf(stderr, "FAILED: Could not hash data.\n");
return 2;
}
/* padd */
rv=GWEN_Padd_PaddWithPkcs1Bt1(buf1, 128);
if (rv) {
fprintf(stderr, "FAILED: Could not padd data.\n");
return 2;
}
/* sign */
buf2=GWEN_Buffer_new(0, 256, 0, 1);
err=GWEN_CryptKey_Sign(privKey, buf1, buf2);
if (!GWEN_Error_IsOk(err)) {
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not sign hash.\n");
return 2;
}
/* hash */
GWEN_Buffer_Reset(buf1);
buf1=GWEN_Buffer_new(0, 256, 0, 1);
rv=GWEN_MD_HashToBuffer("SHA1", testString, strlen(testString), buf1);
if (rv) {
fprintf(stderr, "FAILED: Could not hash data.\n");
return 2;
}
/* padd */
rv=GWEN_Padd_PaddWithPkcs1Bt1(buf1, 128);
if (rv) {
fprintf(stderr, "FAILED: Could not padd data.\n");
return 2;
}
/* verify */
err=GWEN_CryptKey_Verify(pubKey, buf1, buf2);
if (!GWEN_Error_IsOk(err)) {
DBG_ERROR_ERR(0, err);
fprintf(stderr, "FAILED: Could not verify hash.\n");
return 2;
}
return 0;
}
......
int main(int argc, char **argv) {
int rv;
const char *cmd;
rv=check1();
if (rv)
return rv;
if (argc>1)
cmd=argv[1];
else
cmd="check";
if (strcasecmp(cmd, "check")==0) {
rv=check1();
if (rv)
return rv;
rv=check2();
if (rv)
return rv;
}
else if (strcasecmp(cmd, "test1")==0) {
rv=test1();
}
else {
fprintf(stderr, "Unknown command \"%s\"\n", cmd);
return 1;
}
return 0;
}

Auch abrufbar als: Unified diff