#include "ckconfig.h"
#if CRYPTKIT_CIPHERFILE_ENABLE
#include "Crypt.h"
#include "CipherFileDES.h"
#include "falloc.h"
#include "feeDebug.h"
#include <string.h>
feeReturn createRandDES(feePubKey sendPrivKey, feePubKey recvPubKey,
const unsigned char *plainText,
unsigned plainTextLen,
int genSig, unsigned userData, feeCipherFile *cipherFile) {
feeRand frand = NULL;
feeReturn frtn;
unsigned char desKey[FEE_DES_MIN_STATE_SIZE];
unsigned char *encrDesKey = NULL; unsigned encrDesKeyLen;
feeDES des = NULL;
feeFEEDExp feed = NULL;
unsigned char *cipherText = NULL;
unsigned cipherTextLen;
unsigned char *sigData = NULL;
unsigned sigDataLen = 0;
feeCipherFile cfile = NULL;
unsigned char *pubKeyString = NULL; unsigned pubKeyStringLen = 0;
if(recvPubKey == NULL) {
return FR_BadPubKey;
}
frand = feeRandAlloc();
if(frand == NULL) {
frtn = FR_Internal;
goto out;
}
feeRandBytes(frand, desKey, FEE_DES_MIN_STATE_SIZE);
des = feeDESNewWithState(desKey, FEE_DES_MIN_STATE_SIZE);
if(des == NULL) {
frtn = FR_Internal;
goto out;
}
feed = feeFEEDExpNewWithPubKey(recvPubKey, NULL, NULL);
if(feed == NULL) {
frtn = FR_BadPubKey;
goto out;
}
frtn = feeFEEDExpEncrypt(feed,
desKey,
FEE_DES_MIN_STATE_SIZE,
&encrDesKey,
&encrDesKeyLen);
if(frtn) {
goto out;
}
frtn = feeDESEncrypt(des,
plainText,
plainTextLen,
&cipherText,
&cipherTextLen);
if(frtn) {
goto out;
}
if(genSig) {
if(sendPrivKey == NULL) {
frtn = FR_BadPubKey;
goto out;
}
frtn = feePubKeyCreateSignature(sendPrivKey,
cipherText,
cipherTextLen,
&sigData,
&sigDataLen);
if(frtn) {
goto out;
}
frtn = feePubKeyCreateKeyString(sendPrivKey,
(char **)&pubKeyString,
&pubKeyStringLen);
if(frtn) {
frtn = FR_BadPubKey;
goto out;
}
}
cfile = feeCFileNewFromCipherText(CFE_RandDES,
cipherText,
cipherTextLen,
pubKeyString,
pubKeyStringLen,
encrDesKey,
encrDesKeyLen,
sigData,
sigDataLen,
userData);
if(cfile == NULL) {
frtn = FR_Internal;
goto out;
}
out:
if(cipherText) {
ffree(cipherText);
}
if(feed) {
feeFEEDExpFree(feed);
}
if(frand) {
feeRandFree(frand);
}
if(des) {
feeDESFree(des);
}
if(sigData) {
ffree(sigData);
}
if(encrDesKey) {
ffree(encrDesKey);
}
if(pubKeyString) {
ffree(pubKeyString);
}
memset(desKey, 0, FEE_DES_MIN_STATE_SIZE);
*cipherFile = cfile;
return frtn;
}
feeReturn decryptRandDES(feeCipherFile cipherFile,
feePubKey recvPrivKey,
feePubKey sendPubKey, unsigned char **plainText, unsigned *plainTextLen, feeSigStatus *sigStatus) {
feeReturn frtn = FR_Success;
unsigned char *cipherText = NULL;
unsigned cipherTextLen;
feeFEEDExp feed = NULL; feeDES des = NULL; unsigned char *desKey;
unsigned desKeyLen;
unsigned char *encrDesKey = NULL; unsigned encrDesKeyLen;
unsigned char *sigData = NULL;
unsigned sigDataLen;
unsigned char *sendPubKeyStr = NULL;
unsigned sendPubKeyStrLen = 0;
feePubKey parsedSendPubKey = NULL;
if(feeCFileEncrType(cipherFile) != CFE_RandDES) {
frtn = FR_Internal;
goto out;
}
cipherText = feeCFileCipherText(cipherFile, &cipherTextLen);
if(cipherText == NULL) {
frtn = FR_BadCipherFile;
goto out;
}
encrDesKey = feeCFileOtherKeyData(cipherFile, &encrDesKeyLen);
if(encrDesKey == NULL) {
frtn = FR_BadCipherFile;
goto out;
}
feed = feeFEEDExpNewWithPubKey(recvPrivKey, NULL, NULL);
if(feed == NULL) {
frtn = FR_BadPubKey;
goto out;
}
frtn = feeFEEDExpDecrypt(feed,
encrDesKey,
encrDesKeyLen,
&desKey,
&desKeyLen);
if(frtn) {
goto out;
}
if(desKeyLen != FEE_DES_MIN_STATE_SIZE) {
frtn = FR_BadCipherFile;
goto out;
}
des = feeDESNewWithState(desKey, desKeyLen);
if(des == NULL) {
frtn = FR_Internal;
goto out;
}
frtn = feeDESDecrypt(des,
cipherText,
cipherTextLen,
plainText,
plainTextLen);
if(frtn) {
goto out;
}
sigData = feeCFileSigData(cipherFile, &sigDataLen);
if(sigData) {
feeReturn sigFrtn;
if(sendPubKey == NULL) {
sendPubKeyStr = feeCFileSendPubKeyData(cipherFile,
&sendPubKeyStrLen);
if(sendPubKeyStr == NULL) {
*sigStatus = SS_PresentNoKey;
goto out;
}
parsedSendPubKey = feePubKeyAlloc();
frtn = feePubKeyInitFromKeyString(parsedSendPubKey,
(char *)sendPubKeyStr, sendPubKeyStrLen);
if(frtn) {
dbgLog(("parseRandDES: bad sendPubKeyStr\n"));
*sigStatus = SS_PresentNoKey;
goto out;
}
sendPubKey = parsedSendPubKey;
}
sigFrtn = feePubKeyVerifySignature(sendPubKey,
cipherText,
cipherTextLen,
sigData,
sigDataLen);
switch(sigFrtn) {
case FR_Success:
*sigStatus = SS_PresentValid;
break;
default:
*sigStatus = SS_PresentInvalid;
break;
}
}
else {
*sigStatus = SS_NotPresent;
}
out:
if(cipherText) {
ffree(cipherText);
}
if(feed) {
feeFEEDExpFree(feed);
}
if(des) {
feeDESFree(des);
}
if(desKey) {
memset(desKey, 0, desKeyLen);
ffree(desKey);
}
if(encrDesKey) {
ffree(encrDesKey);
}
if(sigData) {
ffree(sigData);
}
if(parsedSendPubKey) {
feePubKeyFree(parsedSendPubKey);
}
if(sendPubKeyStr) {
ffree(sendPubKeyStr);
}
return frtn;
}
feeReturn createPubDES(feePubKey sendPrivKey, feePubKey recvPubKey,
const unsigned char *plainText,
unsigned plainTextLen,
int genSig, unsigned userData, feeCipherFile *cipherFile) {
feeRand frand = NULL;
feeReturn frtn;
unsigned char *desKey;
unsigned desKeyLen;
feeDES des = NULL;
unsigned char *cipherText = NULL;
unsigned cipherTextLen;
unsigned char *sigData = NULL;
unsigned sigDataLen = 0;
feeCipherFile cfile = NULL;
unsigned char *pubKeyString = NULL;
unsigned pubKeyStringLen;
if((sendPrivKey == NULL) || (recvPubKey == NULL)) {
return FR_BadPubKey;
}
frtn = feePubKeyCreateKeyString(sendPrivKey,
(char **)&pubKeyString,
&pubKeyStringLen);
if(frtn) {
goto out;
}
frtn = feePubKeyCreatePad(sendPrivKey,
recvPubKey,
&desKey,
&desKeyLen);
if(frtn) {
goto out;
}
des = feeDESNewWithState(desKey, desKeyLen);
if(des == NULL) {
frtn = FR_Internal;
goto out;
}
frtn = feeDESEncrypt(des,
plainText,
plainTextLen,
&cipherText,
&cipherTextLen);
if(frtn) {
goto out;
}
if(genSig) {
frtn = feePubKeyCreateSignature(sendPrivKey,
cipherText,
cipherTextLen,
&sigData,
&sigDataLen);
if(frtn) {
goto out;
}
}
cfile = feeCFileNewFromCipherText(CFE_PublicDES,
cipherText,
cipherTextLen,
pubKeyString,
pubKeyStringLen,
NULL, 0,
sigData,
sigDataLen,
userData);
if(cfile == NULL) {
frtn = FR_Internal;
goto out;
}
out:
if(cipherText) {
ffree(cipherText);
}
if(frand) {
feeRandFree(frand);
}
if(des) {
feeDESFree(des);
}
if(desKey) {
ffree(desKey);
}
if(sigData) {
ffree(sigData);
}
if(pubKeyString) {
ffree(pubKeyString);
}
*cipherFile = cfile;
return frtn;
}
feeReturn decryptPubDES(feeCipherFile cipherFile,
feePubKey recvPrivKey,
feePubKey sendPubKey,
unsigned char **plainText, unsigned *plainTextLen, feeSigStatus *sigStatus) {
feeReturn frtn = FR_Success;
unsigned char *cipherText = NULL;
unsigned cipherTextLen;
feeDES des = NULL; unsigned char *desKey;
unsigned desKeyLen;
unsigned char *sigData = NULL;
unsigned sigDataLen;
unsigned char *pubKeyString = NULL;
unsigned pubKeyStringLen;
feePubKey decryptPubKey = NULL;
if(feeCFileEncrType(cipherFile) != CFE_PublicDES) {
frtn = FR_Internal;
goto out;
}
cipherText = feeCFileCipherText(cipherFile, &cipherTextLen);
if(cipherText == NULL) {
frtn = FR_BadCipherFile;
goto out;
}
pubKeyString = feeCFileSendPubKeyData(cipherFile, &pubKeyStringLen);
if(pubKeyString == NULL) {
frtn = FR_BadCipherFile;
goto out;
}
decryptPubKey = feePubKeyAlloc();
frtn = feePubKeyInitFromKeyString(decryptPubKey,
(char *)pubKeyString,
pubKeyStringLen);
if(frtn) {
goto out;
}
frtn = feePubKeyCreatePad(recvPrivKey,
decryptPubKey,
&desKey,
&desKeyLen);
if(frtn) {
goto out;
}
if(desKeyLen < FEE_DES_MIN_STATE_SIZE) {
frtn = FR_BadCipherFile;
goto out;
}
des = feeDESNewWithState(desKey, desKeyLen);
if(des == NULL) {
frtn = FR_Internal;
goto out;
}
frtn = feeDESDecrypt(des,
cipherText,
cipherTextLen,
plainText,
plainTextLen);
if(frtn) {
goto out;
}
sigData = feeCFileSigData(cipherFile, &sigDataLen);
if(sigData) {
feeReturn sigFrtn;
if(sendPubKey == NULL) {
sendPubKey = decryptPubKey;
}
sigFrtn = feePubKeyVerifySignature(sendPubKey,
cipherText,
cipherTextLen,
sigData,
sigDataLen);
switch(sigFrtn) {
case FR_Success:
*sigStatus = SS_PresentValid;
break;
default:
*sigStatus = SS_PresentInvalid;
break;
}
}
else {
*sigStatus = SS_NotPresent;
}
out:
if(cipherText) {
ffree(cipherText);
}
if(des) {
feeDESFree(des);
}
if(desKey) {
ffree(desKey);
}
if(pubKeyString) {
ffree(pubKeyString);
}
if(sigData) {
ffree(sigData);
}
if(decryptPubKey) {
feePubKeyFree(decryptPubKey);
}
return frtn;
}
#endif