mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
patchlevel 2
This commit is contained in:
parent
cf783fe54c
commit
762d3d7197
3
TODO
3
TODO
@ -35,3 +35,6 @@
|
|||||||
|
|
||||||
* armor has now some problems.
|
* armor has now some problems.
|
||||||
|
|
||||||
|
* add g10 stuff to Mutt's pgpinvoke.c
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ cipher_SOURCES = blowfish.c \
|
|||||||
dsa.h \
|
dsa.h \
|
||||||
dsa.c \
|
dsa.c \
|
||||||
md.c \
|
md.c \
|
||||||
|
misc.c \
|
||||||
smallprime.c
|
smallprime.c
|
||||||
|
|
||||||
cipher_LIBADD = @CIPHER_EXTRA_OBJS@
|
cipher_LIBADD = @CIPHER_EXTRA_OBJS@
|
||||||
|
@ -60,6 +60,7 @@ cipher_SOURCES = blowfish.c \
|
|||||||
dsa.h \
|
dsa.h \
|
||||||
dsa.c \
|
dsa.c \
|
||||||
md.c \
|
md.c \
|
||||||
|
misc.c \
|
||||||
smallprime.c
|
smallprime.c
|
||||||
|
|
||||||
cipher_LIBADD = @CIPHER_EXTRA_OBJS@
|
cipher_LIBADD = @CIPHER_EXTRA_OBJS@
|
||||||
@ -82,7 +83,7 @@ LIBS = @LIBS@
|
|||||||
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||||
LINK = $(CC) $(LDFLAGS) -o $@
|
LINK = $(CC) $(LDFLAGS) -o $@
|
||||||
cipher_OBJECTS = blowfish.o elgamal.o gost.o md5.o primegen.o random.o \
|
cipher_OBJECTS = blowfish.o elgamal.o gost.o md5.o primegen.o random.o \
|
||||||
rmd160.o sha1.o dsa.o md.o smallprime.o
|
rmd160.o sha1.o dsa.o md.o misc.o smallprime.o
|
||||||
EXTRA_cipher_SOURCES =
|
EXTRA_cipher_SOURCES =
|
||||||
LIBFILES = libcipher.a
|
LIBFILES = libcipher.a
|
||||||
AR = ar
|
AR = ar
|
||||||
@ -101,7 +102,7 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
|
|||||||
TAR = tar
|
TAR = tar
|
||||||
DEP_FILES = $(srcdir)/.deps/blowfish.P $(srcdir)/.deps/dsa.P \
|
DEP_FILES = $(srcdir)/.deps/blowfish.P $(srcdir)/.deps/dsa.P \
|
||||||
$(srcdir)/.deps/elgamal.P $(srcdir)/.deps/gost.P $(srcdir)/.deps/md.P \
|
$(srcdir)/.deps/elgamal.P $(srcdir)/.deps/gost.P $(srcdir)/.deps/md.P \
|
||||||
$(srcdir)/.deps/md5.P $(srcdir)/.deps/primegen.P \
|
$(srcdir)/.deps/md5.P $(srcdir)/.deps/misc.P $(srcdir)/.deps/primegen.P \
|
||||||
$(srcdir)/.deps/random.P $(srcdir)/.deps/rmd160.P \
|
$(srcdir)/.deps/random.P $(srcdir)/.deps/rmd160.P \
|
||||||
$(srcdir)/.deps/sha1.P $(srcdir)/.deps/smallprime.P
|
$(srcdir)/.deps/sha1.P $(srcdir)/.deps/smallprime.P
|
||||||
SOURCES = $(cipher_SOURCES)
|
SOURCES = $(cipher_SOURCES)
|
||||||
|
10
cipher/md.c
10
cipher/md.c
@ -26,17 +26,11 @@
|
|||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
md_okay( int algo )
|
md_okay( int algo )
|
||||||
{
|
{
|
||||||
switch( algo ) {
|
return check_digest_algo( algo );
|
||||||
case DIGEST_ALGO_MD5:
|
|
||||||
case DIGEST_ALGO_RMD160:
|
|
||||||
case DIGEST_ALGO_SHA1:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
return G10ERR_DIGEST_ALGO;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
152
cipher/misc.c
Normal file
152
cipher/misc.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/* misc.c - utility functions
|
||||||
|
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
||||||
|
*
|
||||||
|
* This file is part of G10.
|
||||||
|
*
|
||||||
|
* G10 is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* G10 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "cipher.h"
|
||||||
|
|
||||||
|
|
||||||
|
static struct { const char *name; int algo;} cipher_names[] = {
|
||||||
|
{ "IDEA", CIPHER_ALGO_IDEA },
|
||||||
|
{ "3DES", CIPHER_ALGO_3DES },
|
||||||
|
{ "CAST", CIPHER_ALGO_CAST },
|
||||||
|
{ "BLOWFISH128", CIPHER_ALGO_BLOWFISH128 },
|
||||||
|
{ "ROT_N", CIPHER_ALGO_ROT_N },
|
||||||
|
{ "SAFER_SK128", CIPHER_ALGO_SAFER_SK128 },
|
||||||
|
{ "DES_SK", CIPHER_ALGO_DES_SK },
|
||||||
|
{ "BLOWFISH", CIPHER_ALGO_BLOWFISH },
|
||||||
|
{ "GOST", CIPHER_ALGO_GOST },
|
||||||
|
{NULL} };
|
||||||
|
|
||||||
|
static struct { const char *name; int algo;} pubkey_names[] = {
|
||||||
|
{ "RSA", PUBKEY_ALGO_RSA },
|
||||||
|
{ "RSA-E", PUBKEY_ALGO_RSA_E },
|
||||||
|
{ "RSA-S", PUBKEY_ALGO_RSA_S },
|
||||||
|
{ "ELGAMAL", PUBKEY_ALGO_ELGAMAL },
|
||||||
|
{ "ELG", PUBKEY_ALGO_ELGAMAL },
|
||||||
|
{ "DSA", PUBKEY_ALGO_DSA },
|
||||||
|
{NULL} };
|
||||||
|
|
||||||
|
static struct { const char *name; int algo;} digest_names[] = {
|
||||||
|
{ "MD5", DIGEST_ALGO_MD5 },
|
||||||
|
{ "SHA1", DIGEST_ALGO_SHA1 },
|
||||||
|
{ "SHA-1", DIGEST_ALGO_SHA1 },
|
||||||
|
{ "RMD160", DIGEST_ALGO_RMD160 },
|
||||||
|
{ "RMD-160", DIGEST_ALGO_RMD160 },
|
||||||
|
{ "RIPE-MD-160", DIGEST_ALGO_RMD160 },
|
||||||
|
{NULL} };
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Map a string to the cipher algo
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
string_to_cipher_algo( const char *string )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
for(i=0; s=cipher_names[i].name; i++ )
|
||||||
|
if( !stricmp( s, string ) )
|
||||||
|
return cipher_names[i].algo;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Map a string to the pubkey algo
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
string_to_pubkey_algo( const char *string )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
for(i=0; s=pubkey_names[i].name; i++ )
|
||||||
|
if( !stricmp( s, string ) )
|
||||||
|
return pubkey_names[i].algo;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Map a string to the digest algo
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
string_to_digest_algo( const char *string )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
for(i=0; s=digest_names[i].name; i++ )
|
||||||
|
if( !stricmp( s, string ) )
|
||||||
|
return digest_names[i].algo;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Return 0 if the cipher algo is available
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
check_cipher_algo( int algo )
|
||||||
|
{
|
||||||
|
switch( algo ) {
|
||||||
|
case CIPHER_ALGO_BLOWFISH128:
|
||||||
|
case CIPHER_ALGO_BLOWFISH:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return G10ERR_CIPHER_ALGO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
check_pubkey_algo( int algo )
|
||||||
|
{
|
||||||
|
switch( algo ) {
|
||||||
|
case PUBKEY_ALGO_ELGAMAL:
|
||||||
|
#ifdef HAVE_RSA_CIPHER
|
||||||
|
case PUBKEY_ALGO_RSA:
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return G10ERR_PUBKEY_ALGO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
check_digest_algo( int algo )
|
||||||
|
{
|
||||||
|
switch( algo ) {
|
||||||
|
case DIGEST_ALGO_MD5:
|
||||||
|
case DIGEST_ALGO_RMD160:
|
||||||
|
case DIGEST_ALGO_SHA1:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return G10ERR_DIGEST_ALGO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,11 +78,8 @@
|
|||||||
/* Define if you have the strerror function. */
|
/* Define if you have the strerror function. */
|
||||||
#undef HAVE_STRERROR
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
/* Define if you have the strtol function. */
|
/* Define if you have the strlwr function. */
|
||||||
#undef HAVE_STRTOL
|
#undef HAVE_STRLWR
|
||||||
|
|
||||||
/* Define if you have the strtoul function. */
|
|
||||||
#undef HAVE_STRTOUL
|
|
||||||
|
|
||||||
/* Define if you have the tcgetattr function. */
|
/* Define if you have the tcgetattr function. */
|
||||||
#undef HAVE_TCGETATTR
|
#undef HAVE_TCGETATTR
|
||||||
|
@ -155,7 +155,7 @@ AC_CHECK_SIZEOF(unsigned long, 4)
|
|||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
AC_CHECK_FUNCS(strerror strtol strtoul stpcpy tcgetattr)
|
AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr)
|
||||||
|
|
||||||
dnl check wether we have a random device
|
dnl check wether we have a random device
|
||||||
AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
|
AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
|
||||||
|
@ -165,6 +165,9 @@ no-default-keyring
|
|||||||
no-greeting
|
no-greeting
|
||||||
# suppress the initial copyright etc. messages but do not enter batch mode.
|
# suppress the initial copyright etc. messages but do not enter batch mode.
|
||||||
|
|
||||||
|
no-verbose
|
||||||
|
# set verbose level to 0
|
||||||
|
|
||||||
options filename
|
options filename
|
||||||
# Ignored in option files.
|
# Ignored in option files.
|
||||||
|
|
||||||
|
@ -67,7 +67,8 @@ cipher_filter( void *opaque, int control,
|
|||||||
randomize_buffer( temp, 8, 1 );
|
randomize_buffer( temp, 8, 1 );
|
||||||
temp[8] = temp[6];
|
temp[8] = temp[6];
|
||||||
temp[9] = temp[7];
|
temp[9] = temp[7];
|
||||||
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH ) {
|
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH
|
||||||
|
|| cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 ) {
|
||||||
cfx->bf_ctx = m_alloc_secure( sizeof *cfx->bf_ctx );
|
cfx->bf_ctx = m_alloc_secure( sizeof *cfx->bf_ctx );
|
||||||
blowfish_setkey( cfx->bf_ctx, cfx->dek->key, cfx->dek->keylen );
|
blowfish_setkey( cfx->bf_ctx, cfx->dek->key, cfx->dek->keylen );
|
||||||
blowfish_setiv( cfx->bf_ctx, NULL );
|
blowfish_setiv( cfx->bf_ctx, NULL );
|
||||||
@ -80,13 +81,15 @@ cipher_filter( void *opaque, int control,
|
|||||||
cfx->header=1;
|
cfx->header=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH )
|
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH
|
||||||
|
|| cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 )
|
||||||
blowfish_encode_cfb( cfx->bf_ctx, buf, buf, size);
|
blowfish_encode_cfb( cfx->bf_ctx, buf, buf, size);
|
||||||
if( iobuf_write( a, buf, size ) )
|
if( iobuf_write( a, buf, size ) )
|
||||||
rc = G10ERR_WRITE_FILE;
|
rc = G10ERR_WRITE_FILE;
|
||||||
}
|
}
|
||||||
else if( control == IOBUFCTRL_FREE ) {
|
else if( control == IOBUFCTRL_FREE ) {
|
||||||
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH )
|
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH
|
||||||
|
|| cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 )
|
||||||
m_free(cfx->bf_ctx);
|
m_free(cfx->bf_ctx);
|
||||||
}
|
}
|
||||||
else if( control == IOBUFCTRL_DESC ) {
|
else if( control == IOBUFCTRL_DESC ) {
|
||||||
|
@ -88,7 +88,7 @@ encode_simple( const char *filename, int mode )
|
|||||||
cfx.dek = NULL;
|
cfx.dek = NULL;
|
||||||
if( mode ) {
|
if( mode ) {
|
||||||
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
|
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
|
||||||
cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
cfx.dek->algo = opt.def_cipher_algo;
|
||||||
if( (rc = make_dek_from_passphrase( cfx.dek , 2 )) ) {
|
if( (rc = make_dek_from_passphrase( cfx.dek , 2 )) ) {
|
||||||
m_free(cfx.dek);
|
m_free(cfx.dek);
|
||||||
iobuf_close(inp);
|
iobuf_close(inp);
|
||||||
@ -199,7 +199,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
|||||||
|
|
||||||
/* create a session key */
|
/* create a session key */
|
||||||
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
|
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
|
||||||
cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
cfx.dek->algo = opt.def_cipher_algo;
|
||||||
make_session_key( cfx.dek );
|
make_session_key( cfx.dek );
|
||||||
if( DBG_CIPHER )
|
if( DBG_CIPHER )
|
||||||
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
||||||
@ -269,7 +269,7 @@ encrypt_filter( void *opaque, int control,
|
|||||||
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
||||||
if( !efx->header_okay ) {
|
if( !efx->header_okay ) {
|
||||||
efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek );
|
efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek );
|
||||||
efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
efx->cfx.dek->algo = opt.def_cipher_algo;
|
||||||
make_session_key( efx->cfx.dek );
|
make_session_key( efx->cfx.dek );
|
||||||
if( DBG_CIPHER )
|
if( DBG_CIPHER )
|
||||||
log_hexdump("DEK is: ",
|
log_hexdump("DEK is: ",
|
||||||
|
@ -51,7 +51,8 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
|
|||||||
byte temp[16];
|
byte temp[16];
|
||||||
|
|
||||||
|
|
||||||
if( dek->algo != CIPHER_ALGO_BLOWFISH )
|
if( dek->algo != CIPHER_ALGO_BLOWFISH
|
||||||
|
&& dek->algo != CIPHER_ALGO_BLOWFISH128 )
|
||||||
return G10ERR_CIPHER_ALGO;
|
return G10ERR_CIPHER_ALGO;
|
||||||
if( ed->len && ed->len < 10 )
|
if( ed->len && ed->len < 10 )
|
||||||
log_bug("Nanu\n"); /* oops: found a bug */
|
log_bug("Nanu\n"); /* oops: found a bug */
|
||||||
|
39
g10/g10.c
39
g10/g10.c
@ -169,6 +169,10 @@ main( int argc, char **argv )
|
|||||||
{ 523, "passphrase-fd",1, "\r" },
|
{ 523, "passphrase-fd",1, "\r" },
|
||||||
{ 524, "edit-sig" ,0, "edit a key signature" },
|
{ 524, "edit-sig" ,0, "edit a key signature" },
|
||||||
{ 525, "change-passphrase", 0, "change the passphrase of your secret keyring"},
|
{ 525, "change-passphrase", 0, "change the passphrase of your secret keyring"},
|
||||||
|
{ 526, "no-verbose", 0, "\r"},
|
||||||
|
{ 527, "cipher-algo", 2 , "select default cipher algorithm" },
|
||||||
|
{ 528, "pubkey-algo", 2 , "select default puplic key algorithm" },
|
||||||
|
{ 529, "digest-algo", 2 , "select default message digest algorithm" },
|
||||||
|
|
||||||
{0} };
|
{0} };
|
||||||
ARGPARSE_ARGS pargs;
|
ARGPARSE_ARGS pargs;
|
||||||
@ -194,6 +198,9 @@ main( int argc, char **argv )
|
|||||||
|
|
||||||
|
|
||||||
opt.compress = -1; /* defaults to standard compress level */
|
opt.compress = -1; /* defaults to standard compress level */
|
||||||
|
opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
|
||||||
|
opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL;
|
||||||
|
opt.def_digest_algo = DIGEST_ALGO_RMD160;
|
||||||
|
|
||||||
/* check wether we have a config file on the commandline */
|
/* check wether we have a config file on the commandline */
|
||||||
orig_argc = argc;
|
orig_argc = argc;
|
||||||
@ -298,6 +305,19 @@ main( int argc, char **argv )
|
|||||||
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
|
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
|
||||||
case 524: set_cmd( &cmd, aEditSig); break;
|
case 524: set_cmd( &cmd, aEditSig); break;
|
||||||
case 525: set_cmd( &cmd, aChangePass); break;
|
case 525: set_cmd( &cmd, aChangePass); break;
|
||||||
|
case 526: opt.verbose = 0; opt.list_sigs=0; break;
|
||||||
|
case 527:
|
||||||
|
opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str);
|
||||||
|
break;
|
||||||
|
case 528:
|
||||||
|
opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str);
|
||||||
|
break;
|
||||||
|
case 529:
|
||||||
|
opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
default : errors++; pargs.err = configfp? 1:2; break;
|
default : errors++; pargs.err = configfp? 1:2; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,6 +328,18 @@ main( int argc, char **argv )
|
|||||||
goto next_pass;
|
goto next_pass;
|
||||||
}
|
}
|
||||||
m_free( configname ); configname = NULL;
|
m_free( configname ); configname = NULL;
|
||||||
|
if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) {
|
||||||
|
log_error("selected cipher algorithm is invalid\n");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) ) {
|
||||||
|
log_error("selected pubkey algorithm is invalid\n");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) ) {
|
||||||
|
log_error("selected digest algorithm is invalid\n");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
if( errors )
|
if( errors )
|
||||||
exit(2);
|
exit(2);
|
||||||
|
|
||||||
@ -351,6 +383,13 @@ main( int argc, char **argv )
|
|||||||
else {
|
else {
|
||||||
fname_print = "[stdin]";
|
fname_print = "[stdin]";
|
||||||
fname = NULL;
|
fname = NULL;
|
||||||
|
if( get_passphrase_fd() == 0 ) {
|
||||||
|
/* reading data and passphrase form stdin:
|
||||||
|
* we assume the first line is the passphrase, so
|
||||||
|
* we read it now
|
||||||
|
*/
|
||||||
|
/* FIXME: doit */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( cmd ) {
|
switch( cmd ) {
|
||||||
|
102
g10/keygen.c
102
g10/keygen.c
@ -305,6 +305,7 @@ generate_keypair()
|
|||||||
int rc;
|
int rc;
|
||||||
int algo;
|
int algo;
|
||||||
const char *algo_name;
|
const char *algo_name;
|
||||||
|
char *aname, *acomment, *amail;
|
||||||
|
|
||||||
#ifndef TEST_ALGO
|
#ifndef TEST_ALGO
|
||||||
if( opt.batch || opt.answer_yes || opt.answer_no )
|
if( opt.batch || opt.answer_yes || opt.answer_no )
|
||||||
@ -404,27 +405,102 @@ generate_keypair()
|
|||||||
uid = m_alloc(strlen(TEST_UID)+1);
|
uid = m_alloc(strlen(TEST_UID)+1);
|
||||||
strcpy(uid, TEST_UID);
|
strcpy(uid, TEST_UID);
|
||||||
#else
|
#else
|
||||||
tty_printf( "\nYou need a User-ID to identify your key; please use your name and your\n"
|
tty_printf( "\n"
|
||||||
"email address in this suggested format:\n"
|
"You need a User-ID to identify your key; the software constructs the user id\n"
|
||||||
" \"Heinrich Heine <heinrichh@uni-duesseldorf.de>\n" );
|
"from Real Name, Comment and Email Address in this form:\n"
|
||||||
|
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n" );
|
||||||
uid = NULL;
|
uid = NULL;
|
||||||
|
aname=acomment=amail=NULL;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if( !aname ) {
|
||||||
|
for(;;) {
|
||||||
|
m_free(aname);
|
||||||
|
aname = tty_get("Real name: ");
|
||||||
|
trim_spaces(aname);
|
||||||
|
tty_kill_prompt();
|
||||||
|
if( strpbrk( aname, "<([])>" ) )
|
||||||
|
tty_printf("Invalid character in name\n");
|
||||||
|
else if( strlen(aname) < 5 )
|
||||||
|
tty_printf("Name must be at least 5 characters long\n");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !amail ) {
|
||||||
|
for(;;) {
|
||||||
|
m_free(amail);
|
||||||
|
amail = tty_get("Email address: ");
|
||||||
|
trim_spaces(amail);
|
||||||
|
strlwr(amail);
|
||||||
|
tty_kill_prompt();
|
||||||
|
if( !*amail )
|
||||||
|
break; /* no email address is okay */
|
||||||
|
else if( strcspn( amail, "abcdefghijklmnopqrstuvwxyz_-.@" )
|
||||||
|
|| string_count_chr(amail,'@') != 1
|
||||||
|
|| *amail == '@'
|
||||||
|
|| amail[strlen(amail)-1] == '@'
|
||||||
|
|| amail[strlen(amail)-1] == '.'
|
||||||
|
|| strstr(amail, "..") )
|
||||||
|
tty_printf("Not a valid email address\n");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !acomment ) {
|
||||||
|
for(;;) {
|
||||||
|
m_free(acomment);
|
||||||
|
acomment = tty_get("Comment: ");
|
||||||
|
trim_spaces(acomment);
|
||||||
|
tty_kill_prompt();
|
||||||
|
if( !*acomment )
|
||||||
|
break; /* no comment is okay */
|
||||||
|
else if( strpbrk( acomment, "()" ) )
|
||||||
|
tty_printf("Invalid character in comment\n");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_free(uid);
|
m_free(uid);
|
||||||
tty_printf("\n");
|
uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+10);
|
||||||
uid = tty_get("Your User-ID: ");
|
p = stpcpy(p, aname );
|
||||||
tty_kill_prompt();
|
if( *acomment )
|
||||||
if( strlen(uid) < 5 )
|
p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
|
||||||
tty_printf("Please enter a string of at least 5 characters\n");
|
if( *amail )
|
||||||
else {
|
p = stpcpy(stpcpy(stpcpy(p," <"), amail),">");
|
||||||
tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid);
|
|
||||||
answer = tty_get("Is this correct? ");
|
tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid);
|
||||||
|
for(;;) {
|
||||||
|
answer = tty_get("Edit (N)ame, (C)omment, (E)mail or (O)kay? ");
|
||||||
tty_kill_prompt();
|
tty_kill_prompt();
|
||||||
if( answer_is_yes(answer) ) {
|
if( strlen(answer) > 1 )
|
||||||
m_free(answer);
|
;
|
||||||
|
else if( *answer == 'N' || *answer == 'n' ) {
|
||||||
|
m_free(aname); aname = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( *answer == 'C' || *answer == 'c' ) {
|
||||||
|
m_free(acomment); acomment = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( *answer == 'E' || *answer == 'e' ) {
|
||||||
|
m_free(amail); amail = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( *answer == 'O' || *answer == 'o' ) {
|
||||||
|
m_free(aname); aname = NULL;
|
||||||
|
m_free(acomment); acomment = NULL;
|
||||||
|
m_free(amail); amail = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_free(answer);
|
m_free(answer);
|
||||||
}
|
}
|
||||||
|
m_free(answer);
|
||||||
|
if( !amail && !acomment && !amail )
|
||||||
|
break;
|
||||||
|
m_free(uid); uid = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
127
g10/keyid.c
127
g10/keyid.c
@ -46,6 +46,77 @@ pubkey_letter( int algo )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this is special code for V3 which uses ElGamal and
|
||||||
|
* calculates a fingerprint like V4, but with rmd160
|
||||||
|
* and a version byte of 3. Returns an rmd160 handle, caller must
|
||||||
|
* do rmd160_final()
|
||||||
|
*/
|
||||||
|
|
||||||
|
static RMDHANDLE
|
||||||
|
v3_elg_fingerprint_md( PKT_public_cert *pkc )
|
||||||
|
{
|
||||||
|
RMDHANDLE md;
|
||||||
|
byte *buf1, *buf2, *buf3;
|
||||||
|
byte *p1, *p2, *p3;
|
||||||
|
unsigned n1, n2, n3;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
|
p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
|
||||||
|
for( ; !*p1 && n1; p1++, n1-- ) /* skip leading null bytes */
|
||||||
|
;
|
||||||
|
p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
|
||||||
|
for( ; !*p2 && n2; p2++, n2-- ) /* skip leading null bytes */
|
||||||
|
;
|
||||||
|
p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
|
||||||
|
for( ; !*p3 && n3; p3++, n3-- ) /* skip leading null bytes */
|
||||||
|
;
|
||||||
|
|
||||||
|
/* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
|
||||||
|
n = 14 + n1 + n2 + n3;
|
||||||
|
md = rmd160_open(0);
|
||||||
|
|
||||||
|
rmd160_putchar( md, 0x99 ); /* ctb */
|
||||||
|
rmd160_putchar( md, n >> 8 ); /* 2 byte length header */
|
||||||
|
rmd160_putchar( md, n );
|
||||||
|
rmd160_putchar( md, 3 ); /* version */
|
||||||
|
{ u32 a = pkc->timestamp;
|
||||||
|
rmd160_putchar( md, a >> 24 );
|
||||||
|
rmd160_putchar( md, a >> 16 );
|
||||||
|
rmd160_putchar( md, a >> 8 );
|
||||||
|
rmd160_putchar( md, a );
|
||||||
|
}
|
||||||
|
{ u16 a = pkc->valid_days;
|
||||||
|
rmd160_putchar( md, a >> 8 );
|
||||||
|
rmd160_putchar( md, a );
|
||||||
|
}
|
||||||
|
rmd160_putchar( md, pkc->pubkey_algo );
|
||||||
|
rmd160_putchar( md, n1>>8); rmd160_putchar( md, n1 ); rmd160_write( md, p1, n1 );
|
||||||
|
rmd160_putchar( md, n2>>8); rmd160_putchar( md, n2 ); rmd160_write( md, p2, n2 );
|
||||||
|
rmd160_putchar( md, n3>>8); rmd160_putchar( md, n3 ); rmd160_write( md, p3, n3 );
|
||||||
|
m_free(buf1);
|
||||||
|
m_free(buf2);
|
||||||
|
m_free(buf3);
|
||||||
|
|
||||||
|
return md;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static RMDHANDLE
|
||||||
|
v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
|
||||||
|
{
|
||||||
|
PKT_public_cert pkc;
|
||||||
|
byte *p;
|
||||||
|
|
||||||
|
pkc.pubkey_algo = skc->pubkey_algo;
|
||||||
|
pkc.timestamp = skc->timestamp;
|
||||||
|
pkc.valid_days = skc->valid_days;
|
||||||
|
pkc.pubkey_algo = skc->pubkey_algo;
|
||||||
|
pkc.d.elg.p = skc->d.elg.p;
|
||||||
|
pkc.d.elg.g = skc->d.elg.g;
|
||||||
|
pkc.d.elg.y = skc->d.elg.y;
|
||||||
|
return v3_elg_fingerprint_md( &pkc );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Get the keyid from the secret key certificate and put it into keyid
|
* Get the keyid from the secret key certificate and put it into keyid
|
||||||
@ -61,7 +132,14 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
|
|||||||
keyid = dummy_keyid;
|
keyid = dummy_keyid;
|
||||||
|
|
||||||
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||||
lowbits = mpi_get_keyid( skc->d.elg.y, keyid );
|
const byte *dp;
|
||||||
|
RMDHANDLE md;
|
||||||
|
md = v3_elg_fingerprint_md_skc(skc);
|
||||||
|
dp = rmd160_final( md );
|
||||||
|
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||||
|
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||||
|
lowbits = keyid[1];
|
||||||
|
rmd160_close(md);
|
||||||
}
|
}
|
||||||
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||||
lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
|
lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
|
||||||
@ -87,7 +165,14 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
|
|||||||
keyid = dummy_keyid;
|
keyid = dummy_keyid;
|
||||||
|
|
||||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||||
lowbits = mpi_get_keyid( pkc->d.elg.y, keyid );
|
const byte *dp;
|
||||||
|
RMDHANDLE md;
|
||||||
|
md = v3_elg_fingerprint_md(pkc);
|
||||||
|
dp = rmd160_final( md );
|
||||||
|
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||||
|
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||||
|
lowbits = keyid[1];
|
||||||
|
rmd160_close(md);
|
||||||
}
|
}
|
||||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||||
lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
|
lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
|
||||||
@ -213,47 +298,21 @@ fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
byte *
|
byte *
|
||||||
fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
|
fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
|
||||||
{
|
{
|
||||||
byte *p, *buf, *array;
|
byte *p, *buf, *array;
|
||||||
|
const char *dp;
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
|
||||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||||
RMDHANDLE md;
|
RMDHANDLE md;
|
||||||
const char *dp;
|
md = v3_elg_fingerprint_md(pkc);
|
||||||
|
dp = rmd160_final( md );
|
||||||
md = rmd160_open(0);
|
|
||||||
|
|
||||||
{ u32 a = pkc->timestamp;
|
|
||||||
rmd160_putchar( md, a >> 24 );
|
|
||||||
rmd160_putchar( md, a >> 16 );
|
|
||||||
rmd160_putchar( md, a >> 8 );
|
|
||||||
rmd160_putchar( md, a );
|
|
||||||
}
|
|
||||||
{ u16 a = pkc->valid_days;
|
|
||||||
rmd160_putchar( md, a >> 8 );
|
|
||||||
rmd160_putchar( md, a );
|
|
||||||
}
|
|
||||||
rmd160_putchar( md, pkc->pubkey_algo );
|
|
||||||
p = buf = mpi_get_buffer( pkc->d.elg.p, &n, NULL );
|
|
||||||
for( ; !*p && n; p++, n-- )
|
|
||||||
;
|
|
||||||
rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
|
|
||||||
m_free(buf);
|
|
||||||
p = buf = mpi_get_buffer( pkc->d.elg.g, &n, NULL );
|
|
||||||
for( ; !*p && n; p++, n-- )
|
|
||||||
;
|
|
||||||
rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
|
|
||||||
m_free(buf);
|
|
||||||
p = buf = mpi_get_buffer( pkc->d.elg.y, &n, NULL );
|
|
||||||
for( ; !*p && n; p++, n-- )
|
|
||||||
;
|
|
||||||
rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
|
|
||||||
m_free(buf);
|
|
||||||
|
|
||||||
dp = rmd160_final(md);
|
|
||||||
array = m_alloc( 20 );
|
array = m_alloc( 20 );
|
||||||
len = 20;
|
len = 20;
|
||||||
memcpy(array, dp, 20 );
|
memcpy(array, dp, 20 );
|
||||||
|
@ -24,10 +24,6 @@
|
|||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
|
||||||
#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_BLOWFISH
|
|
||||||
#define DEFAULT_PUBKEY_ALGO PUBKEY_ALGO_ELGAMAL
|
|
||||||
#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_RMD160
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int header_okay;
|
int header_okay;
|
||||||
|
@ -232,7 +232,7 @@ proc_encrypted( CTX c, PACKET *pkt )
|
|||||||
if( !c->dek && !c->last_was_pubkey_enc ) {
|
if( !c->dek && !c->last_was_pubkey_enc ) {
|
||||||
/* assume this is conventional encrypted data */
|
/* assume this is conventional encrypted data */
|
||||||
c->dek = m_alloc_secure( sizeof *c->dek );
|
c->dek = m_alloc_secure( sizeof *c->dek );
|
||||||
c->dek->algo = DEFAULT_CIPHER_ALGO;
|
c->dek->algo = opt.def_cipher_algo;
|
||||||
result = make_dek_from_passphrase( c->dek, 0 );
|
result = make_dek_from_passphrase( c->dek, 0 );
|
||||||
}
|
}
|
||||||
else if( !c->dek )
|
else if( !c->dek )
|
||||||
|
@ -36,9 +36,9 @@ struct {
|
|||||||
int list_sigs; /* list signatures */
|
int list_sigs; /* list signatures */
|
||||||
int no_armor;
|
int no_armor;
|
||||||
int list_packets; /* list-packets mode */
|
int list_packets; /* list-packets mode */
|
||||||
int reserved6;
|
int def_cipher_algo;
|
||||||
int reserved7;
|
int def_pubkey_algo;
|
||||||
int reserved8;
|
int def_digest_algo;
|
||||||
int reserved9;
|
int reserved9;
|
||||||
int reserved10;
|
int reserved10;
|
||||||
int reserved11;
|
int reserved11;
|
||||||
|
@ -131,6 +131,11 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
|
|||||||
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
||||||
dek->algo = CIPHER_ALGO_BLOWFISH;
|
dek->algo = CIPHER_ALGO_BLOWFISH;
|
||||||
break;
|
break;
|
||||||
|
case CIPHER_ALGO_BLOWFISH128:
|
||||||
|
if( i != 18 ) /* length of blowfish-128 is 16 (+2 bytes checksum) */
|
||||||
|
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
||||||
|
dek->algo = CIPHER_ALGO_BLOWFISH128;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rc = G10ERR_CIPHER_ALGO;
|
rc = G10ERR_CIPHER_ALGO;
|
||||||
goto leave;
|
goto leave;
|
||||||
|
@ -41,6 +41,10 @@ make_session_key( DEK *dek )
|
|||||||
dek->keylen = 20;
|
dek->keylen = 20;
|
||||||
randomize_buffer( dek->key, dek->keylen, 1 );
|
randomize_buffer( dek->key, dek->keylen, 1 );
|
||||||
break;
|
break;
|
||||||
|
case CIPHER_ALGO_BLOWFISH128:
|
||||||
|
dek->keylen = 16;
|
||||||
|
randomize_buffer( dek->key, dek->keylen, 1 );
|
||||||
|
break;
|
||||||
|
|
||||||
default: log_bug("invalid algo %d in make_session_key()\n");
|
default: log_bug("invalid algo %d in make_session_key()\n");
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,13 @@ int cipher_debug_mode;
|
|||||||
#define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL )
|
#define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*-- misc.c --*/
|
||||||
|
int string_to_cipher_algo( const char *string );
|
||||||
|
int string_to_pubkey_algo( const char *string );
|
||||||
|
int string_to_digest_algo( const char *string );
|
||||||
|
int check_cipher_algo( int algo );
|
||||||
|
int check_pubkey_algo( int algo );
|
||||||
|
int check_digest_algo( int algo );
|
||||||
|
|
||||||
/*-- md.c --*/
|
/*-- md.c --*/
|
||||||
int md_okay( int algo );
|
int md_okay( int algo );
|
||||||
|
@ -92,10 +92,16 @@ int answer_is_yes( const char *s );
|
|||||||
void free_strlist( STRLIST sl );
|
void free_strlist( STRLIST sl );
|
||||||
#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
|
#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
|
||||||
char *memistr( char *buf, size_t buflen, const char *sub );
|
char *memistr( char *buf, size_t buflen, const char *sub );
|
||||||
|
char *trim_spaces( char *string );
|
||||||
|
int string_count_chr( const char *string, int c );
|
||||||
|
|
||||||
#define stricmp(a,b) strcasecmp((a),(b))
|
#define stricmp(a,b) strcasecmp((a),(b))
|
||||||
#ifndef HAVE_STPCPY
|
#ifndef HAVE_STPCPY
|
||||||
char *stpcpy(char *a,const char *b);
|
char *stpcpy(char *a,const char *b);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_STRLWR
|
||||||
|
char *strlwr(char *a);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/******** some macros ************/
|
/******** some macros ************/
|
||||||
|
@ -350,7 +350,7 @@ iobuf_create( const char *fname )
|
|||||||
file_filter_ctx_t *fcx;
|
file_filter_ctx_t *fcx;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if( !fname ) {
|
if( !fname || (*fname=='-' && !fname[1]) ) {
|
||||||
fp = stdout;
|
fp = stdout;
|
||||||
fname = "[stdout]";
|
fname = "[stdout]";
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,43 @@ memistr( char *buf, size_t buflen, const char *sub )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* remove leading and trailing white spaces
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
trim_spaces( char *str )
|
||||||
|
{
|
||||||
|
char *string, *p, *mark;
|
||||||
|
|
||||||
|
string = str;
|
||||||
|
/* find first non space character */
|
||||||
|
for( p=string; *p && isspace( *(byte*)p ) ; p++ )
|
||||||
|
;
|
||||||
|
/* move characters */
|
||||||
|
for( (mark = NULL); (*string = *p); string++, p++ )
|
||||||
|
if( isspace( *(byte*)p ) ) {
|
||||||
|
if( !mark )
|
||||||
|
mark = string ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mark = NULL ;
|
||||||
|
if( mark )
|
||||||
|
*mark = '\0' ; /* remove trailing spaces */
|
||||||
|
|
||||||
|
return str ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
string_count_chr( const char *string, int c )
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
for(count=0; *string; string++ )
|
||||||
|
if( *string == c )
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
********** missing string functions *********
|
********** missing string functions *********
|
||||||
*********************************************/
|
*********************************************/
|
||||||
@ -78,3 +115,14 @@ stpcpy(char *a,const char *b)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLWR
|
||||||
|
char *
|
||||||
|
strlwr(char *s)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
for(p=s; *p; p++ )
|
||||||
|
*p = tolower(*p);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user