#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "epcrypto.h"
#if EPC_ENABLE
#include <openssl/evp.h>
int
do_crypt_file(
FILE
* in,
FILE
* out,
char
* output,
int
outsize,
int
do_encrypt,
unsigned
char
* begin,
unsigned
char
* header)
{
char
inbuf[1024], outbuf[1024 + 8192];
int
inlen, outlen;
int
blen = 0 ;
int
outcnt = 0 ;
unsigned
char
* key = EPC_KEY ;
unsigned
char
* iv =
"\0x01\0x02\0x03\0x04\0x05\0x06\0x07\0x08"
;
EVP_CIPHER_CTX ctx ;
int
klen ;
int
ivlen ;
if
(output && do_encrypt)
return
-3 ;
EVP_CIPHER_CTX_init(&ctx) ;
EVP_CipherInit(&ctx, EPC_CHIPER, key, iv, do_encrypt);
EVP_CIPHER_CTX_set_key_length(&ctx, EPC_KEYLEN);
klen = EVP_CIPHER_CTX_key_length(&ctx) ;
ivlen = EVP_CIPHER_CTX_iv_length(&ctx) ;
if
(klen > EPC_KEYLEN || ivlen > 8)
return
-6 ;
if
(header)
{
int
hlen =
strlen
(header) ;
if
(!do_encrypt)
{
inlen =
fread
(inbuf, 1, hlen, in);
if
(hlen != inlen ||
memcmp
(inbuf, header, hlen) != 0)
return
-1 ;
}
else
fwrite
(header, 1, hlen, out);
}
if
(begin)
{
blen =
strlen
(begin) ;
if
(do_encrypt)
{
EVP_CipherUpdate(&ctx, outbuf, &outlen, begin, blen) ;
fwrite
(outbuf, 1, outlen, out);
}
}
for
(;;)
{
inlen =
fread
(inbuf, 1, 1024, in);
if
(inlen <= 0)
break
;
EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen) ;
if
(blen && !do_encrypt && blen <= outlen)
{
if
(
memcmp
(outbuf, begin, blen) != 0)
return
-2 ;
if
(blen < outlen)
{
if
(output)
{
if
(outcnt + outlen - blen > outsize)
return
-4 ;
memcpy
(output, outbuf + blen, outlen - blen) ;
output += outlen - blen ;
}
else
{
if
(blen < outlen)
fwrite
(outbuf + blen, 1, outlen - blen, out);
}
}
outcnt += outlen - blen ;
blen = 0 ;
}
else
{
if
(output)
{
if
(outcnt + outlen > outsize)
return
-4 ;
memcpy
(output, outbuf, outlen) ;
output += outlen ;
}
else
{
fwrite
(outbuf, 1, outlen, out);
}
outcnt += outlen ;
}
}
if
(!EVP_CipherFinal(&ctx, outbuf, &outlen))
return
-5;
if
(output)
{
if
(outcnt + outlen > outsize)
return
-4 ;
memcpy
(output, outbuf, outlen) ;
output += outlen ;
}
else
{
fwrite
(outbuf, 1, outlen, out);
}
outcnt += outlen ;
EVP_CIPHER_CTX_cleanup(&ctx);
return
outcnt ;
}
#endif
#ifndef XS_VERSION
int
main (
int
argc,
char
*argv[])
{
#if EPC_ENABLE
FILE
* ifd ;
FILE
* ofd ;
char
* syntax =
"Embperl"
;
int
rc ;
#endif
puts
(
"\nEmbperl encryption tool / Vers. 1.0 / (c) 2001 G.Richter ecos gmbh\n"
) ;
#if EPC_ENABLE == 0
puts
(
"\nEncryption not enabled! see crypto/epcrypt_config.h\n"
) ;
exit
(1) ;
#else
if
(argc < 3)
{
puts
(
"Usage: epcrypto <inputfile> <outputfile> [<syntax>] [<decrypt>]"
) ;
puts
(
" syntax defaults to 'Embperl'"
) ;
puts
(
" decrypt defaults to false"
) ;
exit
(1) ;
}
if
(argc > 3)
syntax = argv[3] ;
if
(!(ifd =
fopen
(argv[1],
"r"
)))
{
printf
(
"Cannot open '%s' for reading (%s)\n"
, argv[1],
strerror
(
errno
) ) ;
exit
(1) ;
}
if
(!(ofd =
fopen
(argv[2],
"w"
)))
{
printf
(
"Cannot open '%s' for writing (%s)\n"
, argv[2],
strerror
(
errno
) ) ;
exit
(1) ;
}
if
((rc = do_crypt_file (ifd, ofd, NULL, 0, argc > 4 && argv[4][0] !=
'\0'
&& argv[4][0] !=
'0'
?0:1, syntax, EPC_HEADER)) <= 0)
{
if
(rc == -1)
{
printf
(
"'%s' is not an Embperl encrypted file\n"
, argv[1]) ;
}
else
if
(rc == -2)
{
printf
(
"'%s' is wrong Syntax for '%s'\n"
, syntax, argv[1]) ;
}
printf
(
"Error while processing '%s' (%s)\n"
, argv[1],
strerror
(
errno
) ) ;
exit
(1) ;
}
return
0 ;
#endif
}
#endif