pluto and scepclient use the random plugin from libstrongswan
This commit is contained in:
parent
8af25c56af
commit
bc2e33ca96
|
@ -957,6 +957,7 @@ if test x$fips_prf = xtrue; then
|
|||
fi
|
||||
if test x$random = xtrue; then
|
||||
libstrongswan_plugins=${libstrongswan_plugins}" random"
|
||||
pluto_plugins=${pluto_plugins}" random"
|
||||
fi
|
||||
if test x$x509 = xtrue; then
|
||||
libstrongswan_plugins=${libstrongswan_plugins}" x509"
|
||||
|
|
|
@ -61,10 +61,15 @@
|
|||
#include <settings.h>
|
||||
#include <plugins/plugin_loader.h>
|
||||
#include <crypto/crypto_factory.h>
|
||||
#include <credentials/credential_factory.h>
|
||||
#include <fetcher/fetcher_manager.h>
|
||||
#include <database/database_factory.h>
|
||||
|
||||
#ifdef NO_CREDENTIAL_FACTORY
|
||||
typedef struct credential_factory_t credential_factory_t;
|
||||
#else
|
||||
#include <credentials/credential_factory.h>
|
||||
#endif
|
||||
|
||||
typedef struct library_t library_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,7 +67,6 @@ static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
|
|||
static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
|
||||
{
|
||||
char error[CURL_ERROR_SIZE];
|
||||
char buf[256];
|
||||
status_t status;
|
||||
|
||||
*result = chunk_empty;
|
||||
|
|
|
@ -18,11 +18,8 @@ db_ops.c db_ops.h \
|
|||
defs.c defs.h \
|
||||
demux.c demux.h \
|
||||
dnskey.c dnskey.h \
|
||||
dsa.c dsa.h \
|
||||
elgamal.c elgamal.h \
|
||||
fetch.c fetch.h \
|
||||
foodgroups.c foodgroups.h \
|
||||
gcryptfix.c gcryptfix.h \
|
||||
id.c id.h \
|
||||
ike_alg.c ike_alg.h \
|
||||
ipsec_doi.c ipsec_doi.h \
|
||||
|
@ -47,7 +44,6 @@ pgp.c pgp.h \
|
|||
pkcs1.c pkcs1.h \
|
||||
pkcs7.c pkcs7.h \
|
||||
plutomain.c \
|
||||
primegen.c smallprime.c \
|
||||
rcv_whack.c rcv_whack.h \
|
||||
server.c server.h \
|
||||
sha1.c sha1.h \
|
||||
|
@ -86,6 +82,7 @@ AM_CFLAGS = \
|
|||
-DPLUGINS=\""${pluto_plugins}\"" \
|
||||
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
|
||||
-DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
|
||||
-DNO_CREDENTIAL_FACTORY \
|
||||
-DPLUTO -DKLIPS -DDEBUG
|
||||
|
||||
pluto_LDADD = \
|
||||
|
|
|
@ -1363,3 +1363,7 @@ void init_constants(void)
|
|||
happy(initsubnet(&ipv4_any, 0, '0', &ipv4_all));
|
||||
happy(initsubnet(&ipv6_any, 0, '0', &ipv6_all));
|
||||
}
|
||||
|
||||
u_char secret_of_the_day[SHA1_DIGEST_SIZE];
|
||||
|
||||
|
||||
|
|
|
@ -1268,4 +1268,7 @@ enum dns_auth_level {
|
|||
/* natt traversal types */
|
||||
extern const char *const natt_type_bitnames[];
|
||||
|
||||
/* secret value for responder cookies */
|
||||
extern u_char secret_of_the_day[SHA1_DIGEST_SIZE];
|
||||
|
||||
#endif /* _CONSTANTS_H */
|
||||
|
|
|
@ -21,10 +21,12 @@
|
|||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "sha1.h"
|
||||
#include "rnd.h"
|
||||
#include "cookie.h"
|
||||
|
||||
const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
|
||||
|
@ -33,8 +35,8 @@ const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
|
|||
* First argument is true if we're to create an Initiator cookie.
|
||||
* Length SHOULD be a multiple of sizeof(u_int32_t).
|
||||
*/
|
||||
void
|
||||
get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
|
||||
void get_cookie(bool initiator, u_int8_t *cookie, int length,
|
||||
const ip_address *addr)
|
||||
{
|
||||
u_char buffer[SHA1_DIGEST_SIZE];
|
||||
SHA1_CTX ctx;
|
||||
|
@ -42,7 +44,11 @@ get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
|
|||
do {
|
||||
if (initiator)
|
||||
{
|
||||
get_rnd_bytes(cookie, length);
|
||||
rng_t *rng;
|
||||
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
|
||||
rng->get_bytes(rng, length, cookie);
|
||||
rng->destroy(rng);
|
||||
}
|
||||
else /* Responder cookie */
|
||||
{
|
||||
|
|
476
src/pluto/dsa.c
476
src/pluto/dsa.c
|
@ -1,476 +0,0 @@
|
|||
/* dsa.c - DSA signature scheme
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG 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.
|
||||
*
|
||||
* GnuPG 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
|
||||
*/
|
||||
|
||||
#ifdef PLUTO
|
||||
#include <gmp.h>
|
||||
#include <freeswan.h>
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "log.h"
|
||||
#include "rnd.h"
|
||||
#include "gcryptfix.h"
|
||||
#else /*! PLUTO */
|
||||
/* #include <config.h> */
|
||||
#endif /* !PLUTO */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef PLUTO
|
||||
/* #include <assert.h> */
|
||||
/* #include "util.h" */
|
||||
/* #include "mpi.h" */
|
||||
/* #include "cipher.h" */
|
||||
#endif
|
||||
|
||||
#include "dsa.h"
|
||||
|
||||
typedef struct {
|
||||
MPI p; /* prime */
|
||||
MPI q; /* group order */
|
||||
MPI g; /* group generator */
|
||||
MPI y; /* g^x mod p */
|
||||
} DSA_public_key;
|
||||
|
||||
|
||||
typedef struct {
|
||||
MPI p; /* prime */
|
||||
MPI q; /* group order */
|
||||
MPI g; /* group generator */
|
||||
MPI y; /* g^x mod p */
|
||||
MPI x; /* secret exponent */
|
||||
} DSA_secret_key;
|
||||
|
||||
|
||||
static MPI gen_k( MPI q );
|
||||
static void test_keys( DSA_secret_key *sk, unsigned qbits );
|
||||
static int check_secret_key( DSA_secret_key *sk );
|
||||
static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
|
||||
static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
|
||||
static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
|
||||
|
||||
static void
|
||||
progress( int c )
|
||||
{
|
||||
fputc( c, stderr );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a random secret exponent k less than q
|
||||
*/
|
||||
static MPI
|
||||
gen_k( MPI q )
|
||||
{
|
||||
MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
|
||||
unsigned int nbits = mpi_get_nbits(q);
|
||||
unsigned int nbytes = (nbits+7)/8;
|
||||
char *rndbuf = NULL;
|
||||
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random k ");
|
||||
for(;;) {
|
||||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
|
||||
if( !rndbuf || nbits < 32 ) {
|
||||
m_free(rndbuf);
|
||||
rndbuf = get_random_bits( nbits, 1, 1 );
|
||||
}
|
||||
else { /* change only some of the higher bits */
|
||||
/* we could imporove this by directly requesting more memory
|
||||
* at the first call to get_random_bits() and use this the here
|
||||
* maybe it is easier to do this directly in random.c */
|
||||
char *pp = get_random_bits( 32, 1, 1 );
|
||||
memcpy( rndbuf,pp, 4 );
|
||||
m_free(pp);
|
||||
}
|
||||
mpi_set_buffer( k, rndbuf, nbytes, 0 );
|
||||
if( mpi_test_bit( k, nbits-1 ) )
|
||||
mpi_set_highbit( k, nbits-1 );
|
||||
else {
|
||||
mpi_set_highbit( k, nbits-1 );
|
||||
mpi_clear_bit( k, nbits-1 );
|
||||
}
|
||||
|
||||
if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */
|
||||
if( DBG_CIPHER )
|
||||
progress('+');
|
||||
continue; /* no */
|
||||
}
|
||||
if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
|
||||
if( DBG_CIPHER )
|
||||
progress('-');
|
||||
continue; /* no */
|
||||
}
|
||||
break; /* okay */
|
||||
}
|
||||
m_free(rndbuf);
|
||||
if( DBG_CIPHER )
|
||||
progress('\n');
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_keys( DSA_secret_key *sk, unsigned qbits )
|
||||
{
|
||||
DSA_public_key pk;
|
||||
MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
|
||||
MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
|
||||
MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
|
||||
|
||||
pk.p = sk->p;
|
||||
pk.q = sk->q;
|
||||
pk.g = sk->g;
|
||||
pk.y = sk->y;
|
||||
/*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/
|
||||
{ char *p = get_random_bits( qbits, 0, 0 );
|
||||
mpi_set_buffer( test, p, (qbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
sign( out1_a, out1_b, test, sk );
|
||||
if( !verify( out1_a, out1_b, test, &pk ) )
|
||||
log_fatal("DSA:: sign, verify failed\n");
|
||||
|
||||
mpi_free( test );
|
||||
mpi_free( out1_a );
|
||||
mpi_free( out1_b );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a DSA key pair with a key of size NBITS
|
||||
* Returns: 2 structures filled with all needed values
|
||||
* and an array with the n-1 factors of (p-1)
|
||||
*/
|
||||
static void
|
||||
generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
||||
{
|
||||
MPI p; /* the prime */
|
||||
MPI q; /* the 160 bit prime factor */
|
||||
MPI g; /* the generator */
|
||||
MPI y; /* g^x mod p */
|
||||
MPI x; /* the secret exponent */
|
||||
MPI h, e; /* helper */
|
||||
unsigned qbits;
|
||||
byte *rndbuf;
|
||||
|
||||
assert( nbits >= 512 && nbits <= 1024 );
|
||||
|
||||
qbits = 160;
|
||||
p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
|
||||
/* get q out of factors */
|
||||
q = mpi_copy((*ret_factors)[0]);
|
||||
if( mpi_get_nbits(q) != qbits )
|
||||
BUG();
|
||||
|
||||
/* find a generator g (h and e are helpers)*/
|
||||
/* e = (p-1)/q */
|
||||
e = mpi_alloc( mpi_get_nlimbs(p) );
|
||||
mpi_sub_ui( e, p, 1 );
|
||||
mpi_fdiv_q( e, e, q );
|
||||
g = mpi_alloc( mpi_get_nlimbs(p) );
|
||||
h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
|
||||
do {
|
||||
mpi_add_ui( h, h, 1 );
|
||||
/* g = h^e mod p */
|
||||
mpi_powm( g, h, e, p );
|
||||
} while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
|
||||
|
||||
/* select a random number which has these properties:
|
||||
* 0 < x < q-1
|
||||
* This must be a very good random number because this
|
||||
* is the secret part. */
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random x ");
|
||||
assert( qbits >= 160 );
|
||||
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
|
||||
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
|
||||
rndbuf = NULL;
|
||||
do {
|
||||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
if( !rndbuf )
|
||||
rndbuf = get_random_bits( qbits, 2, 1 );
|
||||
else { /* change only some of the higher bits (= 2 bytes)*/
|
||||
char *r = get_random_bits( 16, 2, 1 );
|
||||
memcpy(rndbuf, r, 16/8 );
|
||||
m_free(r);
|
||||
}
|
||||
mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
|
||||
mpi_clear_highbit( x, qbits+1 );
|
||||
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
|
||||
m_free(rndbuf);
|
||||
mpi_free( e );
|
||||
mpi_free( h );
|
||||
|
||||
/* y = g^x mod p */
|
||||
y = mpi_alloc( mpi_get_nlimbs(p) );
|
||||
mpi_powm( y, g, x, p );
|
||||
|
||||
if( DBG_CIPHER ) {
|
||||
progress('\n');
|
||||
log_mpidump("dsa p= ", p );
|
||||
log_mpidump("dsa q= ", q );
|
||||
log_mpidump("dsa g= ", g );
|
||||
log_mpidump("dsa y= ", y );
|
||||
log_mpidump("dsa x= ", x );
|
||||
}
|
||||
|
||||
/* copy the stuff to the key structures */
|
||||
sk->p = p;
|
||||
sk->q = q;
|
||||
sk->g = g;
|
||||
sk->y = y;
|
||||
sk->x = x;
|
||||
|
||||
/* now we can test our keys (this should never fail!) */
|
||||
test_keys( sk, qbits );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Test whether the secret key is valid.
|
||||
* Returns: if this is a valid key.
|
||||
*/
|
||||
static int
|
||||
check_secret_key( DSA_secret_key *sk )
|
||||
{
|
||||
int rc;
|
||||
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
|
||||
|
||||
mpi_powm( y, sk->g, sk->x, sk->p );
|
||||
rc = !mpi_cmp( y, sk->y );
|
||||
mpi_free( y );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Make a DSA signature from HASH and put it into r and s.
|
||||
*/
|
||||
|
||||
static void
|
||||
sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
|
||||
{
|
||||
MPI k;
|
||||
MPI kinv;
|
||||
MPI tmp;
|
||||
|
||||
/* select a random k with 0 < k < q */
|
||||
k = gen_k( skey->q );
|
||||
|
||||
/* r = (a^k mod p) mod q */
|
||||
mpi_powm( r, skey->g, k, skey->p );
|
||||
mpi_fdiv_r( r, r, skey->q );
|
||||
|
||||
/* kinv = k^(-1) mod q */
|
||||
kinv = mpi_alloc( mpi_get_nlimbs(k) );
|
||||
mpi_invm(kinv, k, skey->q );
|
||||
|
||||
/* s = (kinv * ( hash + x * r)) mod q */
|
||||
tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
|
||||
mpi_mul( tmp, skey->x, r );
|
||||
mpi_add( tmp, tmp, hash );
|
||||
mpi_mulm( s , kinv, tmp, skey->q );
|
||||
|
||||
mpi_free(k);
|
||||
mpi_free(kinv);
|
||||
mpi_free(tmp);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Returns true if the signature composed from R and S is valid.
|
||||
*/
|
||||
static int
|
||||
verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
|
||||
{
|
||||
int rc;
|
||||
MPI w, u1, u2, v;
|
||||
MPI base[3];
|
||||
MPI exp[3];
|
||||
|
||||
|
||||
if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
|
||||
return 0; /* assertion 0 < r < q failed */
|
||||
if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
|
||||
return 0; /* assertion 0 < s < q failed */
|
||||
|
||||
w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
|
||||
u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
|
||||
u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
|
||||
v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
|
||||
|
||||
/* w = s^(-1) mod q */
|
||||
mpi_invm( w, s, pkey->q );
|
||||
|
||||
/* u1 = (hash * w) mod q */
|
||||
mpi_mulm( u1, hash, w, pkey->q );
|
||||
|
||||
/* u2 = r * w mod q */
|
||||
mpi_mulm( u2, r, w, pkey->q );
|
||||
|
||||
/* v = g^u1 * y^u2 mod p mod q */
|
||||
base[0] = pkey->g; exp[0] = u1;
|
||||
base[1] = pkey->y; exp[1] = u2;
|
||||
base[2] = NULL; exp[2] = NULL;
|
||||
mpi_mulpowm( v, base, exp, pkey->p );
|
||||
mpi_fdiv_r( v, v, pkey->q );
|
||||
|
||||
rc = !mpi_cmp( v, r );
|
||||
|
||||
mpi_free(w);
|
||||
mpi_free(u1);
|
||||
mpi_free(u2);
|
||||
mpi_free(v);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************
|
||||
************** interface ******************
|
||||
*********************************************/
|
||||
|
||||
int
|
||||
dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
|
||||
{
|
||||
DSA_secret_key sk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
|
||||
generate( &sk, nbits, retfactors );
|
||||
skey[0] = sk.p;
|
||||
skey[1] = sk.q;
|
||||
skey[2] = sk.g;
|
||||
skey[3] = sk.y;
|
||||
skey[4] = sk.x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dsa_check_secret_key( int algo, MPI *skey )
|
||||
{
|
||||
DSA_secret_key sk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
|
||||
return G10ERR_BAD_MPI;
|
||||
|
||||
sk.p = skey[0];
|
||||
sk.q = skey[1];
|
||||
sk.g = skey[2];
|
||||
sk.y = skey[3];
|
||||
sk.x = skey[4];
|
||||
if( !check_secret_key( &sk ) )
|
||||
return G10ERR_BAD_SECKEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
||||
{
|
||||
DSA_secret_key sk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
|
||||
return G10ERR_BAD_MPI;
|
||||
|
||||
sk.p = skey[0];
|
||||
sk.q = skey[1];
|
||||
sk.g = skey[2];
|
||||
sk.y = skey[3];
|
||||
sk.x = skey[4];
|
||||
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
|
||||
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
|
||||
sign( resarr[0], resarr[1], data, &sk );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
|
||||
{
|
||||
DSA_public_key pk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
if( !data[0] || !data[1] || !hash
|
||||
|| !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
|
||||
return G10ERR_BAD_MPI;
|
||||
|
||||
pk.p = pkey[0];
|
||||
pk.q = pkey[1];
|
||||
pk.g = pkey[2];
|
||||
pk.y = pkey[3];
|
||||
if( !verify( data[0], data[1], hash, &pk ) )
|
||||
return G10ERR_BAD_SIGN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned
|
||||
dsa_get_nbits( int algo, MPI *pkey )
|
||||
{
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return 0;
|
||||
return mpi_get_nbits( pkey[0] );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return some information about the algorithm. We need algo here to
|
||||
* distinguish different flavors of the algorithm.
|
||||
* Returns: A pointer to string describing the algorithm or NULL if
|
||||
* the ALGO is invalid.
|
||||
* Usage: Bit 0 set : allows signing
|
||||
* 1 set : allows encryption
|
||||
*/
|
||||
const char *
|
||||
dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
|
||||
int *use )
|
||||
{
|
||||
*npkey = 4;
|
||||
*nskey = 5;
|
||||
*nenc = 0;
|
||||
*nsig = 2;
|
||||
|
||||
switch( algo ) {
|
||||
case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA";
|
||||
default: *use = 0; return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* dsa.h - DSA signature scheme
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG 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.
|
||||
*
|
||||
* GnuPG 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
|
||||
*/
|
||||
#ifndef G10_DSA_H
|
||||
#define G10_DSA_H
|
||||
|
||||
int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
|
||||
int dsa_check_secret_key( int algo, MPI *skey );
|
||||
int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
|
||||
int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
int (*cmp)(void *, MPI), void *opaquev );
|
||||
unsigned dsa_get_nbits( int algo, MPI *pkey );
|
||||
const char *dsa_get_info( int algo, int *npkey, int *nskey,
|
||||
int *nenc, int *nsig, int *use );
|
||||
|
||||
#endif /*G10_DSA_H*/
|
|
@ -28,7 +28,6 @@
|
|||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "log.h"
|
||||
#include "rnd.h"
|
||||
#include "gcryptfix.h"
|
||||
#else /*! PLUTO */
|
||||
/* #include <config.h> */
|
||||
|
|
|
@ -1,281 +0,0 @@
|
|||
/* Routines to make gcrypt routines feel at home in Pluto.
|
||||
* Copyright (C) 1999 D. Hugh Redelmeier.
|
||||
*
|
||||
* This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gmp.h>
|
||||
#include <freeswan.h>
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "log.h"
|
||||
#include "rnd.h"
|
||||
#include "gcryptfix.h" /* includes <gmp.h> "defs.h" "rnd.h" */
|
||||
|
||||
MPI
|
||||
mpi_alloc( unsigned nlimbs UNUSED )
|
||||
{
|
||||
MPI n = malloc(sizeof *n);
|
||||
|
||||
mpz_init(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
MPI
|
||||
mpi_alloc_secure( unsigned nlimbs )
|
||||
{
|
||||
return mpi_alloc(nlimbs);
|
||||
}
|
||||
|
||||
MPI
|
||||
mpi_alloc_set_ui( unsigned long u)
|
||||
{
|
||||
MPI n = malloc(sizeof *n);
|
||||
|
||||
mpz_init_set_ui(n, u);
|
||||
return n;
|
||||
}
|
||||
|
||||
MPI
|
||||
mpi_copy( MPI a )
|
||||
{
|
||||
MPI n = malloc(sizeof *n);
|
||||
|
||||
mpz_init_set(n, a);
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
mpi_free( MPI a )
|
||||
{
|
||||
mpz_clear(a);
|
||||
free(a);
|
||||
}
|
||||
|
||||
int
|
||||
mpi_divisible_ui(MPI dividend, ulong divisor )
|
||||
{
|
||||
ulong rem;
|
||||
mpz_t remtoo;
|
||||
|
||||
mpz_init(remtoo);
|
||||
rem = mpz_mod_ui(remtoo, dividend, divisor);
|
||||
mpz_clear(remtoo);
|
||||
return rem == 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
mpi_trailing_zeros( MPI a )
|
||||
{
|
||||
return mpz_scan1(a, 0);
|
||||
}
|
||||
|
||||
unsigned
|
||||
mpi_get_nbits( MPI a )
|
||||
{
|
||||
return mpz_sizeinbase(a, 2);
|
||||
}
|
||||
|
||||
int
|
||||
mpi_test_bit( MPI a, unsigned n )
|
||||
{
|
||||
/* inspired by gmp/mpz/clrbit.c */
|
||||
mp_size_t li = n / mp_bits_per_limb;
|
||||
|
||||
if (li >= a->_mp_size)
|
||||
return 0;
|
||||
return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
|
||||
}
|
||||
|
||||
void
|
||||
mpi_set_bit( MPI a, unsigned n )
|
||||
{
|
||||
mpz_setbit(a, n);
|
||||
}
|
||||
|
||||
void
|
||||
mpi_clear_bit( MPI a, unsigned n )
|
||||
{
|
||||
mpz_clrbit(a, n);
|
||||
}
|
||||
|
||||
void
|
||||
mpi_clear_highbit( MPI a, unsigned n )
|
||||
{
|
||||
/* This seems whacky, but what do I know. */
|
||||
mpz_fdiv_r_2exp(a, a, n);
|
||||
}
|
||||
|
||||
void
|
||||
mpi_set_highbit( MPI a, unsigned n )
|
||||
{
|
||||
/* This seems whacky, but what do I know. */
|
||||
mpz_fdiv_r_2exp(a, a, n+1);
|
||||
mpz_setbit(a, n);
|
||||
}
|
||||
|
||||
void
|
||||
mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign )
|
||||
{
|
||||
/* this is a lot like n_to_mpz */
|
||||
size_t i;
|
||||
|
||||
passert(sign == 0); /* we won't hit any negative numbers */
|
||||
mpz_init_set_ui(a, 0);
|
||||
|
||||
for (i = 0; i != nbytes; i++)
|
||||
{
|
||||
mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
|
||||
mpz_add_ui(a, a, buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
u_char *
|
||||
get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
|
||||
{
|
||||
size_t nbytes = (nbits+7)/8;
|
||||
u_char *b = malloc(nbytes);
|
||||
|
||||
get_rnd_bytes(b, nbytes);
|
||||
return b;
|
||||
}
|
||||
/**************** from gnupg-1.0.0/mpi/mpi-mpow.c
|
||||
* RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
|
||||
*/
|
||||
#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) mpi_mulm( (w), (u), (v), (m) )
|
||||
|
||||
static int
|
||||
build_index( MPI *exparray, int k, int i, int t )
|
||||
{
|
||||
int j, bitno;
|
||||
int index = 0;
|
||||
|
||||
bitno = t-i;
|
||||
for(j=k-1; j >= 0; j-- ) {
|
||||
index <<= 1;
|
||||
if( mpi_test_bit( exparray[j], bitno ) )
|
||||
index |= 1;
|
||||
}
|
||||
/*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
|
||||
return index;
|
||||
}
|
||||
|
||||
void
|
||||
mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
|
||||
{
|
||||
int k; /* number of elements */
|
||||
int t; /* bit size of largest exponent */
|
||||
int i, j, idx;
|
||||
MPI *G; /* table with precomputed values of size 2^k */
|
||||
MPI tmp;
|
||||
#ifdef USE_BARRETT
|
||||
MPI barrett_y, barrett_r1, barrett_r2;
|
||||
int barrett_k;
|
||||
#endif
|
||||
|
||||
for(k=0; basearray[k]; k++ )
|
||||
;
|
||||
passert(k);
|
||||
for(t=0, i=0; (tmp=exparray[i]); i++ ) {
|
||||
/*log_mpidump("exp: ", tmp );*/
|
||||
j = mpi_get_nbits(tmp);
|
||||
if( j > t )
|
||||
t = j;
|
||||
}
|
||||
/*log_mpidump("mod: ", m );*/
|
||||
passert(i==k);
|
||||
passert(t);
|
||||
passert( k < 10 );
|
||||
|
||||
#ifdef PLUTO
|
||||
m_alloc_ptrs_clear(G, 1<<k);
|
||||
#else
|
||||
G = m_alloc_clear( (1<<k) * sizeof *G );
|
||||
#endif
|
||||
|
||||
#ifdef USE_BARRETT
|
||||
barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
|
||||
#endif
|
||||
/* and calculate */
|
||||
tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
|
||||
mpi_set_ui( res, 1 );
|
||||
for(i = 1; i <= t; i++ ) {
|
||||
barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
|
||||
barrett_r1, barrett_r2 );
|
||||
idx = build_index( exparray, k, i, t );
|
||||
passert( idx >= 0 && idx < (1<<k) );
|
||||
if( !G[idx] ) {
|
||||
if( !idx )
|
||||
G[0] = mpi_alloc_set_ui( 1 );
|
||||
else {
|
||||
for(j=0; j < k; j++ ) {
|
||||
if( (idx & (1<<j) ) ) {
|
||||
if( !G[idx] )
|
||||
G[idx] = mpi_copy( basearray[j] );
|
||||
else
|
||||
barrett_mulm( G[idx], G[idx], basearray[j],
|
||||
m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
|
||||
}
|
||||
}
|
||||
if( !G[idx] )
|
||||
G[idx] = mpi_alloc(0);
|
||||
}
|
||||
}
|
||||
barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
mpi_free(tmp);
|
||||
#ifdef USE_BARRETT
|
||||
mpi_free(barrett_y);
|
||||
mpi_free(barrett_r1);
|
||||
mpi_free(barrett_r2);
|
||||
#endif
|
||||
for(i=0; i < (1<<k); i++ )
|
||||
mpi_free(G[i]);
|
||||
m_free(G);
|
||||
}
|
||||
|
||||
void
|
||||
log_mpidump( const char *text UNUSED, MPI a )
|
||||
{
|
||||
/* Print number in hex -- helpful to see if they match bytes.
|
||||
* Humans are not going to do arithmetic with the large numbers!
|
||||
* Much code adapted from mpz_to_n.
|
||||
*/
|
||||
u_char buf[8048]; /* this ought to be big enough */
|
||||
size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
|
||||
MP_INT temp1, temp2;
|
||||
int i;
|
||||
|
||||
passert(len <= sizeof(buf));
|
||||
|
||||
mpz_init(&temp1);
|
||||
mpz_init(&temp2);
|
||||
|
||||
mpz_set(&temp1, a);
|
||||
|
||||
for (i = len-1; i >= 0; i--)
|
||||
{
|
||||
buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
|
||||
mpz_set(&temp1, &temp2);
|
||||
}
|
||||
|
||||
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
|
||||
mpz_clear(&temp1);
|
||||
mpz_clear(&temp2);
|
||||
|
||||
#ifdef DEBUG
|
||||
DBG_dump(text, buf, len);
|
||||
#endif /* DEBUG */
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/* Definitions to make gcrypt routines feel at home in Pluto.
|
||||
* Copyright (C) 1999 D. Hugh Redelmeier.
|
||||
*
|
||||
* This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#define DBG_CIPHER 1 /* some day we'll do this right */
|
||||
|
||||
/* Simulate MPI routines with gmp routines.
|
||||
* gmp's MP_INT is a stuct; MPI's MPI is a pointer to an analogous struct.
|
||||
* gmp's mpz_t is an array of one of these structs to enable magic pointer
|
||||
* conversions to make the notation convenient (but confusing).
|
||||
*/
|
||||
typedef u_char byte;
|
||||
typedef MP_INT *MPI;
|
||||
|
||||
#define BITS_PER_MPI_LIMB mp_bits_per_limb
|
||||
|
||||
extern MPI mpi_alloc( unsigned nlimbs );
|
||||
extern MPI mpi_alloc_secure( unsigned nlimbs );
|
||||
#define mpi_alloc_like(n) mpi_alloc(mpi_get_nlimbs(n))
|
||||
extern MPI mpi_alloc_set_ui( unsigned long u);
|
||||
#define mpi_set_ui(w, u) mpz_set_ui(w, u)
|
||||
#define mpi_set(w, u) mpz_set(w, u)
|
||||
extern void mpi_free( MPI a );
|
||||
extern MPI mpi_copy( MPI a );
|
||||
extern unsigned mpi_get_nbits( MPI a );
|
||||
#define mpi_get_nlimbs(a) ((a)->_mp_alloc) /* dirty, but useless */
|
||||
extern void mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign );
|
||||
extern unsigned mpi_trailing_zeros( MPI a );
|
||||
extern int mpi_test_bit( MPI a, unsigned n );
|
||||
extern void mpi_set_bit( MPI a, unsigned n );
|
||||
extern void mpi_clear_bit( MPI a, unsigned n );
|
||||
extern void mpi_clear_highbit( MPI a, unsigned n );
|
||||
extern void mpi_set_highbit( MPI a, unsigned n );
|
||||
#define mpi_cmp_ui(u, v) mpz_cmp_ui((u), (v))
|
||||
#define mpi_cmp(u, v) mpz_cmp((u), (v))
|
||||
#define mpi_is_neg(n) (mpz_sgn(n) < 0)
|
||||
#define mpi_add(w, u, v) mpz_add((w), (u), (v))
|
||||
#define mpi_add_ui(w, u, v) mpz_add_ui((w), (u), (v))
|
||||
#define mpi_sub_ui(w, u, v) mpz_sub_ui((w), (u), (v))
|
||||
#define mpi_subm( w, u, v, m) { mpz_sub( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
|
||||
#define mpi_mul( w, u, v) mpz_mul( (w), (u), (v))
|
||||
#define mpi_mul_ui( w, u, v) mpz_mul_ui( (w), (u), (v))
|
||||
#define mpi_mulm( w, u, v, m) { mpz_mul( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
|
||||
#define mpi_fdiv_q(quot, dividend, divisor) mpz_fdiv_q((quot), (dividend), (divisor))
|
||||
#define mpi_fdiv_r( rem, dividend, divisor ) mpz_fdiv_r( (rem), (dividend), (divisor) )
|
||||
#define mpi_fdiv_r_ui( rem, dividend, divisor ) mpz_fdiv_r_ui( (rem), (dividend), (divisor) )
|
||||
#define mpi_tdiv_q_2exp( w, u, count ) mpz_tdiv_q_2exp( (w), (u), (count) )
|
||||
extern int mpi_divisible_ui(MPI dividend, ulong divisor );
|
||||
#define mpi_powm( res, base, exp, mod) mpz_powm( res, base, exp, mod)
|
||||
extern void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
|
||||
#define mpi_gcd( g, a, b ) ( mpz_gcd( (g), (a), (b) ), !mpi_cmp_ui( (g), 1))
|
||||
#define mpi_invm( x, a, n ) mpz_invert( (x), (a), (n) )
|
||||
|
||||
#ifdef DEBUG
|
||||
# define log_debug(f...) DBG_log(f)
|
||||
#else
|
||||
# define log_debug(f...) do ; while (0) /* do nothing, carefully */
|
||||
#endif
|
||||
#define log_fatal(f...) exit_log(f) /* overreaction? */
|
||||
extern void log_mpidump( const char *text, MPI a );
|
||||
|
||||
#define assert(p) passert(p)
|
||||
#define BUG() passert(FALSE)
|
||||
|
||||
#define m_alloc_ptrs_clear(pp, n) { \
|
||||
int c = (n); \
|
||||
(pp) = malloc((n) * sizeof(*(pp))); \
|
||||
while (c > 0) (pp)[--c] = NULL; \
|
||||
}
|
||||
|
||||
extern u_char *get_random_bits(size_t nbits, int level, int secure);
|
||||
#define m_alloc(sz) malloc((sz)) /* not initialized */
|
||||
#define m_free(n) free(n) /* always freeing something from get_random_bits */
|
||||
|
||||
/* declarations from gnupg-1.0.0/include/cipher.h */
|
||||
/*-- primegen.c --*/
|
||||
MPI generate_secret_prime( unsigned nbits );
|
||||
MPI generate_public_prime( unsigned nbits );
|
||||
MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
||||
MPI g, MPI **factors );
|
||||
|
||||
#define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not for v3)*/
|
||||
#define PUBKEY_ALGO_DSA 17
|
||||
#define PUBKEY_ALGO_ELGAMAL 20 /* sign and encrypt elgamal */
|
||||
|
||||
#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E)
|
||||
|
||||
#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
|
||||
#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
|
||||
|
||||
/* from gnupg-1.0.0/include/errors.h */
|
||||
|
||||
#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */
|
||||
#define G10ERR_BAD_SECKEY 7 /* Bad secret key */
|
||||
#define G10ERR_BAD_SIGN 8 /* Bad signature */
|
||||
#define G10ERR_BAD_MPI 30
|
||||
|
||||
/*-- smallprime.c --*/
|
||||
extern ushort small_prime_numbers[];
|
|
@ -28,7 +28,10 @@
|
|||
|
||||
#include <freeswan.h>
|
||||
#include <ipsec_policy.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
|
@ -52,7 +55,6 @@
|
|||
#include "server.h"
|
||||
#include "spdb.h"
|
||||
#include "timer.h"
|
||||
#include "rnd.h"
|
||||
#include "ipsec_doi.h" /* needs demux.h and state.h */
|
||||
#include "whack.h"
|
||||
#include "fetch.h"
|
||||
|
@ -120,9 +122,8 @@ echo_hdr(struct msg_digest *md, bool enc, u_int8_t np)
|
|||
* We make the leap that the length should be that of the group
|
||||
* (see quoted passage at start of ACCEPT_KE).
|
||||
*/
|
||||
static void
|
||||
compute_dh_shared(struct state *st, const chunk_t g
|
||||
, const struct oakley_group_desc *group)
|
||||
static void compute_dh_shared(struct state *st, const chunk_t g,
|
||||
const struct oakley_group_desc *group)
|
||||
{
|
||||
MP_INT mp_g, mp_shared;
|
||||
struct timeval tv0, tv1;
|
||||
|
@ -158,16 +159,19 @@ compute_dh_shared(struct state *st, const chunk_t g
|
|||
/* if we haven't already done so, compute a local DH secret (st->st_sec) and
|
||||
* the corresponding public value (g). This is emitted as a KE payload.
|
||||
*/
|
||||
static bool
|
||||
build_and_ship_KE(struct state *st, chunk_t *g
|
||||
, const struct oakley_group_desc *group, pb_stream *outs, u_int8_t np)
|
||||
static bool build_and_ship_KE(struct state *st, chunk_t *g,
|
||||
const struct oakley_group_desc *group,
|
||||
pb_stream *outs, u_int8_t np)
|
||||
{
|
||||
if (!st->st_sec_in_use)
|
||||
{
|
||||
u_char tmp[LOCALSECRETSIZE];
|
||||
MP_INT mp_g;
|
||||
|
||||
get_rnd_bytes(tmp, LOCALSECRETSIZE);
|
||||
rng_t *rng;
|
||||
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
|
||||
rng->get_bytes(rng, LOCALSECRETSIZE, tmp);
|
||||
rng->destroy(rng);
|
||||
st->st_sec_in_use = TRUE;
|
||||
n_to_mpz(&st->st_sec, tmp, LOCALSECRETSIZE);
|
||||
|
||||
|
@ -192,10 +196,9 @@ build_and_ship_KE(struct state *st, chunk_t *g
|
|||
* Diffie-Hellman group enforced, if necessary, by pre-pending the
|
||||
* value with zeros.
|
||||
*/
|
||||
static notification_t
|
||||
accept_KE(chunk_t *dest, const char *val_name
|
||||
, const struct oakley_group_desc *gr
|
||||
, pb_stream *pbs)
|
||||
static notification_t accept_KE(chunk_t *dest, const char *val_name,
|
||||
const struct oakley_group_desc *gr,
|
||||
pb_stream *pbs)
|
||||
{
|
||||
if (pbs_left(pbs) != gr->bytes)
|
||||
{
|
||||
|
@ -216,9 +219,8 @@ accept_KE(chunk_t *dest, const char *val_name
|
|||
* Check and accept optional Quick Mode KE payload for PFS.
|
||||
* Extends ACCEPT_PFS to check whether KE is allowed or required.
|
||||
*/
|
||||
static notification_t
|
||||
accept_PFS_KE(struct msg_digest *md, chunk_t *dest
|
||||
, const char *val_name, const char *msg_name)
|
||||
static notification_t accept_PFS_KE(struct msg_digest *md, chunk_t *dest,
|
||||
const char *val_name, const char *msg_name)
|
||||
{
|
||||
struct state *st = md->st;
|
||||
struct payload_digest *const ke_pd = md->chain[ISAKMP_NEXT_KE];
|
||||
|
@ -249,18 +251,20 @@ accept_PFS_KE(struct msg_digest *md, chunk_t *dest
|
|||
return NOTHING_WRONG;
|
||||
}
|
||||
|
||||
static bool
|
||||
build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np
|
||||
, const char *name)
|
||||
static bool build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np,
|
||||
const char *name)
|
||||
{
|
||||
rng_t *rng;
|
||||
|
||||
free(n->ptr);
|
||||
*n = chunk_create(malloc(DEFAULT_NONCE_SIZE), DEFAULT_NONCE_SIZE);
|
||||
get_rnd_bytes(n->ptr, DEFAULT_NONCE_SIZE);
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
rng->get_bytes(rng, DEFAULT_NONCE_SIZE, n->ptr);
|
||||
rng->destroy(rng);
|
||||
return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name);
|
||||
}
|
||||
|
||||
static bool
|
||||
collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
|
||||
static bool collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
|
||||
{
|
||||
struct connection *d = find_host_connection(&md->iface->addr
|
||||
, pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY);
|
||||
|
@ -295,8 +299,8 @@ collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
|
|||
return *top != NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, u_int8_t np)
|
||||
static bool build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs,
|
||||
u_int8_t np)
|
||||
{
|
||||
pb_stream cr_pbs;
|
||||
struct isakmp_cr cr_hd;
|
||||
|
@ -321,10 +325,10 @@ build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, u_int8_t np)
|
|||
* whether to send the notification, based on the type and the
|
||||
* destination, if we care to.
|
||||
*/
|
||||
static void
|
||||
send_notification(struct state *sndst, u_int16_t type, struct state *encst,
|
||||
msgid_t msgid, u_char *icookie, u_char *rcookie,
|
||||
u_char *spi, size_t spisize, u_char protoid)
|
||||
static void send_notification(struct state *sndst, u_int16_t type,
|
||||
struct state *encst, msgid_t msgid,
|
||||
u_char *icookie, u_char *rcookie,
|
||||
u_char *spi, size_t spisize, u_char protoid)
|
||||
{
|
||||
u_char buffer[1024];
|
||||
pb_stream pbs, r_hdr_pbs;
|
||||
|
@ -451,9 +455,8 @@ send_notification(struct state *sndst, u_int16_t type, struct state *encst,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
send_notification_from_state(struct state *st, enum state_kind state,
|
||||
u_int16_t type)
|
||||
void send_notification_from_state(struct state *st, enum state_kind state,
|
||||
u_int16_t type)
|
||||
{
|
||||
struct state *p1st;
|
||||
|
||||
|
@ -487,8 +490,7 @@ send_notification_from_state(struct state *st, enum state_kind state,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
send_notification_from_md(struct msg_digest *md, u_int16_t type)
|
||||
void send_notification_from_md(struct msg_digest *md, u_int16_t type)
|
||||
{
|
||||
/**
|
||||
* Create a dummy state to be able to use send_packet in
|
||||
|
@ -519,8 +521,7 @@ send_notification_from_md(struct msg_digest *md, u_int16_t type)
|
|||
* inbound IPSEC SAs. Does nothing if no such SAs are being deleted.
|
||||
* Delete Notifications cannot announce deletion of outbound IPSEC/ISAKMP SAs.
|
||||
*/
|
||||
void
|
||||
send_delete(struct state *st)
|
||||
void send_delete(struct state *st)
|
||||
{
|
||||
pb_stream reply_pbs;
|
||||
pb_stream r_hdr_pbs;
|
||||
|
@ -686,8 +687,8 @@ send_delete(struct state *st)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
|
||||
void accept_delete(struct state *st, struct msg_digest *md,
|
||||
struct payload_digest *p)
|
||||
{
|
||||
struct isakmp_delete *d = &(p->payload.delete);
|
||||
size_t sizespi;
|
||||
|
@ -869,8 +870,7 @@ accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
|
|||
* rfc2408 3.6 Transform Payload.
|
||||
* Note: it talks about 4 BYTE boundaries!
|
||||
*/
|
||||
void
|
||||
close_message(pb_stream *pbs)
|
||||
void close_message(pb_stream *pbs)
|
||||
{
|
||||
size_t padding = pad_up(pbs_offset(pbs), 4);
|
||||
|
||||
|
@ -1062,12 +1062,8 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
|
|||
return STF_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ipsecdoi_initiate(int whack_sock
|
||||
, struct connection *c
|
||||
, lset_t policy
|
||||
, unsigned long try
|
||||
, so_serial_t replacing)
|
||||
void ipsecdoi_initiate(int whack_sock, struct connection *c, lset_t policy,
|
||||
unsigned long try, so_serial_t replacing)
|
||||
{
|
||||
/* If there's already an ISAKMP SA established, use that and
|
||||
* go directly to Quick Mode. We are even willing to use one
|
||||
|
@ -1114,8 +1110,7 @@ ipsecdoi_initiate(int whack_sock
|
|||
* - duplicate whack fd, if live.
|
||||
* Does not delete the old state -- someone else will do that.
|
||||
*/
|
||||
void
|
||||
ipsecdoi_replace(struct state *st, unsigned long try)
|
||||
void ipsecdoi_replace(struct state *st, unsigned long try)
|
||||
{
|
||||
int whack_sock = dup_any(st->st_whack_sock);
|
||||
lset_t policy = st->st_policy;
|
||||
|
@ -1160,8 +1155,7 @@ ipsecdoi_replace(struct state *st, unsigned long try)
|
|||
/* SKEYID for preshared keys.
|
||||
* See draft-ietf-ipsec-ike-01.txt 4.1
|
||||
*/
|
||||
static bool
|
||||
skeyid_preshared(struct state *st)
|
||||
static bool skeyid_preshared(struct state *st)
|
||||
{
|
||||
const chunk_t *pss = get_preshared_secret(st->st_connection);
|
||||
|
||||
|
@ -1206,8 +1200,7 @@ skeyid_digisig(struct state *st)
|
|||
/* Generate the SKEYID_* and new IV
|
||||
* See draft-ietf-ipsec-ike-01.txt 4.1
|
||||
*/
|
||||
static bool
|
||||
generate_skeyids_iv(struct state *st)
|
||||
static bool generate_skeyids_iv(struct state *st)
|
||||
{
|
||||
/* Generate the SKEYID */
|
||||
switch (st->st_oakley.auth)
|
||||
|
@ -1347,12 +1340,10 @@ generate_skeyids_iv(struct state *st)
|
|||
*/
|
||||
|
||||
typedef void (*hash_update_t)(union hash_ctx *, const u_char *, size_t) ;
|
||||
static void
|
||||
main_mode_hash_body(struct state *st
|
||||
, bool hashi /* Initiator? */
|
||||
, const pb_stream *idpl /* ID payload, as PBS */
|
||||
, union hash_ctx *ctx
|
||||
, void (*hash_update_void)(void *, const u_char *input, size_t))
|
||||
|
||||
static void main_mode_hash_body(struct state *st, bool hashi,
|
||||
const pb_stream *idpl, union hash_ctx *ctx,
|
||||
void (*hash_update_void)(void *, const u_char *input, size_t))
|
||||
{
|
||||
#define HASH_UPDATE_T (union hash_ctx *, const u_char *input, unsigned int len)
|
||||
hash_update_t hash_update=(hash_update_t) hash_update_void;
|
||||
|
@ -1401,10 +1392,8 @@ main_mode_hash_body(struct state *st
|
|||
}
|
||||
|
||||
static size_t /* length of hash */
|
||||
main_mode_hash(struct state *st
|
||||
, u_char *hash_val /* resulting bytes */
|
||||
, bool hashi /* Initiator? */
|
||||
, const pb_stream *idpl) /* ID payload, as PBS; cur must be at end */
|
||||
main_mode_hash(struct state *st, u_char *hash_val, bool hashi,
|
||||
const pb_stream *idpl)
|
||||
{
|
||||
struct hmac_ctx ctx;
|
||||
|
||||
|
@ -1438,10 +1427,8 @@ main_mode_sha1(struct state *st
|
|||
* Use PKCS#1 version 1.5 encryption of hash (called
|
||||
* RSAES-PKCS1-V1_5) in PKCS#2.
|
||||
*/
|
||||
static size_t
|
||||
RSA_sign_hash(struct connection *c
|
||||
, u_char sig_val[RSA_MAX_OCTETS]
|
||||
, const u_char *hash_val, size_t hash_len)
|
||||
static size_t RSA_sign_hash(struct connection *c, u_char sig_val[RSA_MAX_OCTETS],
|
||||
const u_char *hash_val, size_t hash_len)
|
||||
{
|
||||
size_t sz = 0;
|
||||
smartcard_t *sc = c->spd.this.sc;
|
||||
|
@ -1511,10 +1498,9 @@ RSA_sign_hash(struct connection *c
|
|||
* it is not: the knowledge of the private key allows more efficient (i.e.
|
||||
* different) computation for encryption.
|
||||
*/
|
||||
static err_t
|
||||
try_RSA_signature(const u_char hash_val[MAX_DIGEST_LEN], size_t hash_len
|
||||
, const pb_stream *sig_pbs, pubkey_t *kr
|
||||
, struct state *st)
|
||||
static err_t try_RSA_signature(const u_char hash_val[MAX_DIGEST_LEN],
|
||||
size_t hash_len, const pb_stream *sig_pbs,
|
||||
pubkey_t *kr, struct state *st)
|
||||
{
|
||||
const u_char *sig_val = sig_pbs->cur;
|
||||
size_t sig_len = pbs_left(sig_pbs);
|
||||
|
@ -1644,10 +1630,8 @@ struct tac_state {
|
|||
char *tn; /* roof of tried[] */
|
||||
};
|
||||
|
||||
static bool
|
||||
take_a_crack(struct tac_state *s
|
||||
, pubkey_t *kr
|
||||
, const char *story USED_BY_DEBUG)
|
||||
static bool take_a_crack(struct tac_state *s, pubkey_t *kr,
|
||||
const char *story USED_BY_DEBUG)
|
||||
{
|
||||
err_t ugh = try_RSA_signature(s->hash_val, s->hash_len, s->sig_pbs
|
||||
, kr, s->st);
|
||||
|
@ -1679,17 +1663,13 @@ take_a_crack(struct tac_state *s
|
|||
}
|
||||
}
|
||||
|
||||
static stf_status
|
||||
RSA_check_signature(const struct id* peer
|
||||
, struct state *st
|
||||
, const u_char hash_val[MAX_DIGEST_LEN]
|
||||
, size_t hash_len
|
||||
, const pb_stream *sig_pbs
|
||||
static stf_status RSA_check_signature(const struct id* peer, struct state *st,
|
||||
const u_char hash_val[MAX_DIGEST_LEN],
|
||||
size_t hash_len, const pb_stream *sig_pbs,
|
||||
#ifdef USE_KEYRR
|
||||
, const pubkey_list_t *keys_from_dns
|
||||
const pubkey_list_t *keys_from_dns,
|
||||
#endif /* USE_KEYRR */
|
||||
, const struct gw_info *gateways_from_dns
|
||||
)
|
||||
const struct gw_info *gateways_from_dns)
|
||||
{
|
||||
const struct connection *c = st->st_connection;
|
||||
struct tac_state s;
|
||||
|
@ -1838,8 +1818,8 @@ RSA_check_signature(const struct id* peer
|
|||
}
|
||||
}
|
||||
|
||||
static notification_t
|
||||
accept_nonce(struct msg_digest *md, chunk_t *dest, const char *name)
|
||||
static notification_t accept_nonce(struct msg_digest *md, chunk_t *dest,
|
||||
const char *name)
|
||||
{
|
||||
pb_stream *nonce_pbs = &md->chain[ISAKMP_NEXT_NONCE]->pbs;
|
||||
size_t len = pbs_left(nonce_pbs);
|
||||
|
@ -1902,9 +1882,9 @@ encrypt_message(pb_stream *pbs, struct state *st)
|
|||
* Used by: quick_outI1, quick_inI1_outR1 (twice), quick_inR1_outI2
|
||||
* (see RFC 2409 "IKE" 5.5, pg. 18 or draft-ietf-ipsec-ike-01.txt 6.2 pg 25)
|
||||
*/
|
||||
static size_t
|
||||
quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
|
||||
, const struct state *st, const msgid_t *msgid, bool hash2)
|
||||
static size_t quick_mode_hash12(u_char *dest, const u_char *start,
|
||||
const u_char *roof, const struct state *st,
|
||||
const msgid_t *msgid, bool hash2)
|
||||
{
|
||||
struct hmac_ctx ctx;
|
||||
|
||||
|
@ -1935,8 +1915,7 @@ quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
|
|||
* NOTE: this hash (unlike HASH(1) and HASH(2)) ONLY covers the
|
||||
* Message ID and Nonces. This is a mistake.
|
||||
*/
|
||||
static size_t
|
||||
quick_mode_hash3(u_char *dest, struct state *st)
|
||||
static size_t quick_mode_hash3(u_char *dest, struct state *st)
|
||||
{
|
||||
struct hmac_ctx ctx;
|
||||
|
||||
|
@ -1953,8 +1932,7 @@ quick_mode_hash3(u_char *dest, struct state *st)
|
|||
/* Compute Phase 2 IV.
|
||||
* Uses Phase 1 IV from st_iv; puts result in st_new_iv.
|
||||
*/
|
||||
void
|
||||
init_phase2_iv(struct state *st, const msgid_t *msgid)
|
||||
void init_phase2_iv(struct state *st, const msgid_t *msgid)
|
||||
{
|
||||
const struct hash_desc *h = st->st_oakley.hasher;
|
||||
union hash_ctx ctx;
|
||||
|
@ -1981,9 +1959,8 @@ init_phase2_iv(struct state *st, const msgid_t *msgid)
|
|||
* Note: this is not called from demux.c
|
||||
*/
|
||||
|
||||
static bool
|
||||
emit_subnet_id(ip_subnet *net
|
||||
, u_int8_t np, u_int8_t protoid, u_int16_t port, pb_stream *outs)
|
||||
static bool emit_subnet_id(ip_subnet *net, u_int8_t np, u_int8_t protoid,
|
||||
u_int16_t port, pb_stream *outs)
|
||||
{
|
||||
struct isakmp_ipsec_id id;
|
||||
pb_stream id_pbs;
|
||||
|
@ -2018,13 +1995,9 @@ emit_subnet_id(ip_subnet *net
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
stf_status
|
||||
quick_outI1(int whack_sock
|
||||
, struct state *isakmp_sa
|
||||
, struct connection *c
|
||||
, lset_t policy
|
||||
, unsigned long try
|
||||
, so_serial_t replacing)
|
||||
stf_status quick_outI1(int whack_sock, struct state *isakmp_sa,
|
||||
struct connection *c, lset_t policy, unsigned long try,
|
||||
so_serial_t replacing)
|
||||
{
|
||||
struct state *st = duplicate_state(isakmp_sa);
|
||||
pb_stream reply; /* not really a reply */
|
||||
|
@ -2236,8 +2209,7 @@ quick_outI1(int whack_sock
|
|||
/*
|
||||
* Decode the CERT payload of Phase 1.
|
||||
*/
|
||||
static void
|
||||
decode_cert(struct msg_digest *md)
|
||||
static void decode_cert(struct msg_digest *md)
|
||||
{
|
||||
struct payload_digest *p;
|
||||
|
||||
|
@ -2291,8 +2263,7 @@ decode_cert(struct msg_digest *md)
|
|||
/*
|
||||
* Decode the CR payload of Phase 1.
|
||||
*/
|
||||
static void
|
||||
decode_cr(struct msg_digest *md, struct connection *c)
|
||||
static void decode_cr(struct msg_digest *md, struct connection *c)
|
||||
{
|
||||
struct payload_digest *p;
|
||||
|
||||
|
@ -2342,8 +2313,7 @@ decode_cr(struct msg_digest *md, struct connection *c)
|
|||
* We must be called before SIG or HASH are decoded since we
|
||||
* may change the peer's RSA key or ID.
|
||||
*/
|
||||
static bool
|
||||
decode_peer_id(struct msg_digest *md, struct id *peer)
|
||||
static bool decode_peer_id(struct msg_digest *md, struct id *peer)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
struct payload_digest *const id_pld = md->chain[ISAKMP_NEXT_ID];
|
||||
|
@ -2457,8 +2427,8 @@ decode_peer_id(struct msg_digest *md, struct id *peer)
|
|||
* - if the initiation was explicit, we'd be ignoring user's intent
|
||||
* - if opportunistic, we'll lose our HOLD info
|
||||
*/
|
||||
static bool
|
||||
switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
|
||||
static bool switch_connection(struct msg_digest *md, struct id *peer,
|
||||
bool initiator)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
struct connection *c = st->st_connection;
|
||||
|
@ -2569,11 +2539,8 @@ switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
|
|||
* Rejects 0.0.0.0/32 or IPv6 equivalent because
|
||||
* (1) it is wrong and (2) we use this value for inband signalling.
|
||||
*/
|
||||
static bool
|
||||
decode_net_id(struct isakmp_ipsec_id *id
|
||||
, pb_stream *id_pbs
|
||||
, ip_subnet *net
|
||||
, const char *which)
|
||||
static bool decode_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
|
||||
ip_subnet *net, const char *which)
|
||||
{
|
||||
const struct af_info *afi = NULL;
|
||||
|
||||
|
@ -2737,14 +2704,9 @@ decode_net_id(struct isakmp_ipsec_id *id
|
|||
}
|
||||
|
||||
/* like decode, but checks that what is received matches what was sent */
|
||||
static bool
|
||||
|
||||
check_net_id(struct isakmp_ipsec_id *id
|
||||
, pb_stream *id_pbs
|
||||
, u_int8_t *protoid
|
||||
, u_int16_t *port
|
||||
, ip_subnet *net
|
||||
, const char *which)
|
||||
static bool check_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
|
||||
u_int8_t *protoid, u_int16_t *port, ip_subnet *net,
|
||||
const char *which)
|
||||
{
|
||||
ip_subnet net_temp;
|
||||
|
||||
|
@ -2763,8 +2725,7 @@ check_net_id(struct isakmp_ipsec_id *id
|
|||
/*
|
||||
* look for the existence of a non-expiring preloaded public key
|
||||
*/
|
||||
static bool
|
||||
has_preloaded_public_key(struct state *st)
|
||||
static bool has_preloaded_public_key(struct state *st)
|
||||
{
|
||||
struct connection *c = st->st_connection;
|
||||
|
||||
|
@ -2797,10 +2758,8 @@ has_preloaded_public_key(struct state *st)
|
|||
* RFC 2409 "IKE" section 5.5
|
||||
* specifies how this is to be done.
|
||||
*/
|
||||
static void
|
||||
compute_proto_keymat(struct state *st
|
||||
, u_int8_t protoid
|
||||
, struct ipsec_proto_info *pi)
|
||||
static void compute_proto_keymat(struct state *st, u_int8_t protoid,
|
||||
struct ipsec_proto_info *pi)
|
||||
{
|
||||
size_t needed_len = 0; /* bytes of keying material needed */
|
||||
|
||||
|
@ -2945,8 +2904,7 @@ compute_proto_keymat(struct state *st
|
|||
DBG_dump("Peer KEYMAT computed:\n", pi->peer_keymat, pi->keymat_len));
|
||||
}
|
||||
|
||||
static void
|
||||
compute_keymats(struct state *st)
|
||||
static void compute_keymats(struct state *st)
|
||||
{
|
||||
if (st->st_ah.present)
|
||||
compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah);
|
||||
|
@ -3245,8 +3203,7 @@ main_inI1_outR1(struct msg_digest *md)
|
|||
*
|
||||
* We must verify that the proposal received matches one we sent.
|
||||
*/
|
||||
stf_status
|
||||
main_inR1_outI2(struct msg_digest *md)
|
||||
stf_status main_inR1_outI2(struct msg_digest *md)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
|
||||
|
@ -3346,8 +3303,7 @@ main_inR1_outI2(struct msg_digest *md)
|
|||
* HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
|
||||
* --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
|
||||
*/
|
||||
stf_status
|
||||
main_inI2_outR2(struct msg_digest *md)
|
||||
stf_status main_inI2_outR2(struct msg_digest *md)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
|
||||
|
@ -3487,8 +3443,7 @@ main_inI2_outR2(struct msg_digest *md)
|
|||
* SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
|
||||
* --> HDR*, HASH_I
|
||||
*/
|
||||
stf_status
|
||||
main_inR2_outI3(struct msg_digest *md)
|
||||
stf_status main_inR2_outI3(struct msg_digest *md)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
|
||||
|
@ -3672,8 +3627,8 @@ struct key_continuation {
|
|||
|
||||
typedef stf_status (key_tail_fn)(struct msg_digest *md
|
||||
, struct key_continuation *kc);
|
||||
static void
|
||||
report_key_dns_failure(struct id *id, err_t ugh)
|
||||
|
||||
static void report_key_dns_failure(struct id *id, err_t ugh)
|
||||
{
|
||||
char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
|
||||
|
||||
|
@ -3843,10 +3798,8 @@ main_id_and_auth(struct msg_digest *md
|
|||
* to find authentication, or we run out of things
|
||||
* to try.
|
||||
*/
|
||||
static void
|
||||
key_continue(struct adns_continuation *cr
|
||||
, err_t ugh
|
||||
, key_tail_fn *tail)
|
||||
static void key_continue(struct adns_continuation *cr, err_t ugh,
|
||||
key_tail_fn *tail)
|
||||
{
|
||||
struct key_continuation *kc = (void *)cr;
|
||||
struct state *st = kc->md->st;
|
||||
|
@ -3898,14 +3851,12 @@ key_continue(struct adns_continuation *cr
|
|||
*/
|
||||
static key_tail_fn main_inI3_outR3_tail; /* forward */
|
||||
|
||||
stf_status
|
||||
main_inI3_outR3(struct msg_digest *md)
|
||||
stf_status main_inI3_outR3(struct msg_digest *md)
|
||||
{
|
||||
return main_inI3_outR3_tail(md, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
|
||||
static void main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
|
||||
{
|
||||
key_continue(cr, ugh, main_inI3_outR3_tail);
|
||||
}
|
||||
|
@ -4077,21 +4028,18 @@ main_inI3_outR3_tail(struct msg_digest *md
|
|||
|
||||
static key_tail_fn main_inR3_tail; /* forward */
|
||||
|
||||
stf_status
|
||||
main_inR3(struct msg_digest *md)
|
||||
stf_status main_inR3(struct msg_digest *md)
|
||||
{
|
||||
return main_inR3_tail(md, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
main_inR3_continue(struct adns_continuation *cr, err_t ugh)
|
||||
static void main_inR3_continue(struct adns_continuation *cr, err_t ugh)
|
||||
{
|
||||
key_continue(cr, ugh, main_inR3_tail);
|
||||
}
|
||||
|
||||
static stf_status
|
||||
main_inR3_tail(struct msg_digest *md
|
||||
, struct key_continuation *kc)
|
||||
static stf_status main_inR3_tail(struct msg_digest *md,
|
||||
struct key_continuation *kc)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
|
||||
|
@ -4233,8 +4181,7 @@ struct verify_oppo_continuation {
|
|||
static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b
|
||||
, struct adns_continuation *ac);
|
||||
|
||||
stf_status
|
||||
quick_inI1_outR1(struct msg_digest *md)
|
||||
stf_status quick_inI1_outR1(struct msg_digest *md)
|
||||
{
|
||||
const struct state *const p1st = md->st;
|
||||
struct connection *c = p1st->st_connection;
|
||||
|
@ -4341,8 +4288,7 @@ report_verify_failure(struct verify_oppo_bundle *b, err_t ugh)
|
|||
, fgwb, cb, which, ugh);
|
||||
}
|
||||
|
||||
static void
|
||||
quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
|
||||
static void quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
|
||||
{
|
||||
stf_status r;
|
||||
struct verify_oppo_continuation *vc = (void *)cr;
|
||||
|
@ -4372,9 +4318,8 @@ quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
|
|||
cur_state = NULL;
|
||||
}
|
||||
|
||||
static stf_status
|
||||
quick_inI1_outR1_start_query(struct verify_oppo_bundle *b
|
||||
, enum verify_oppo_step next_step)
|
||||
static stf_status quick_inI1_outR1_start_query(struct verify_oppo_bundle *b,
|
||||
enum verify_oppo_step next_step)
|
||||
{
|
||||
struct msg_digest *md = b->md;
|
||||
struct state *p1st = md->st;
|
||||
|
@ -4489,10 +4434,10 @@ quick_inI1_outR1_start_query(struct verify_oppo_bundle *b
|
|||
}
|
||||
}
|
||||
|
||||
static enum verify_oppo_step
|
||||
quick_inI1_outR1_process_answer(struct verify_oppo_bundle *b
|
||||
, struct adns_continuation *ac
|
||||
, struct state *p1st)
|
||||
static enum verify_oppo_step quick_inI1_outR1_process_answer(
|
||||
struct verify_oppo_bundle *b,
|
||||
struct adns_continuation *ac,
|
||||
struct state *p1st)
|
||||
{
|
||||
struct connection *c = p1st->st_connection;
|
||||
enum verify_oppo_step next_step = vos_our_client;
|
||||
|
@ -4665,9 +4610,8 @@ quick_inI1_outR1_process_answer(struct verify_oppo_bundle *b
|
|||
return next_step;
|
||||
}
|
||||
|
||||
static stf_status
|
||||
quick_inI1_outR1_tail(struct verify_oppo_bundle *b
|
||||
, struct adns_continuation *ac)
|
||||
static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
|
||||
struct adns_continuation *ac)
|
||||
{
|
||||
struct msg_digest *md = b->md;
|
||||
struct state *const p1st = md->st;
|
||||
|
@ -5019,8 +4963,7 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
|
|||
/*
|
||||
* Initialize RFC 3706 Dead Peer Detection
|
||||
*/
|
||||
static void
|
||||
dpd_init(struct state *st)
|
||||
static void dpd_init(struct state *st)
|
||||
{
|
||||
struct state *p1st = find_state(st->st_icookie, st->st_rcookie
|
||||
, &st->st_connection->spd.that.host_addr, 0);
|
||||
|
@ -5044,8 +4987,7 @@ dpd_init(struct state *st)
|
|||
* (see RFC 2409 "IKE" 5.5)
|
||||
* Installs inbound and outbound IPsec SAs, routing, etc.
|
||||
*/
|
||||
stf_status
|
||||
quick_inR1_outI2(struct msg_digest *md)
|
||||
stf_status quick_inR1_outI2(struct msg_digest *md)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
const struct connection *c = st->st_connection;
|
||||
|
@ -5197,8 +5139,7 @@ quick_inR1_outI2(struct msg_digest *md)
|
|||
* (see RFC 2409 "IKE" 5.5)
|
||||
* Installs outbound IPsec SAs, routing, etc.
|
||||
*/
|
||||
stf_status
|
||||
quick_inI2(struct msg_digest *md)
|
||||
stf_status quick_inI2(struct msg_digest *md)
|
||||
{
|
||||
struct state *const st = md->st;
|
||||
|
||||
|
@ -5243,9 +5184,8 @@ quick_inI2(struct msg_digest *md)
|
|||
return STF_OK;
|
||||
}
|
||||
|
||||
static stf_status
|
||||
send_isakmp_notification(struct state *st, u_int16_t type
|
||||
, const void *data, size_t len)
|
||||
static stf_status send_isakmp_notification(struct state *st, u_int16_t type,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
msgid_t msgid;
|
||||
pb_stream reply;
|
||||
|
@ -5350,8 +5290,7 @@ send_isakmp_notification(struct state *st, u_int16_t type
|
|||
/*
|
||||
* DPD Out Initiator
|
||||
*/
|
||||
void
|
||||
dpd_outI(struct state *p2st)
|
||||
void dpd_outI(struct state *p2st)
|
||||
{
|
||||
struct state *st;
|
||||
u_int32_t seqno;
|
||||
|
@ -5411,8 +5350,12 @@ dpd_outI(struct state *p2st)
|
|||
|
||||
if (!st->st_dpd_seqno)
|
||||
{
|
||||
rng_t *rng;
|
||||
|
||||
/* Get a non-zero random value that has room to grow */
|
||||
get_rnd_bytes((u_char *)&st->st_dpd_seqno, sizeof(st->st_dpd_seqno));
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
rng->get_bytes(rng, sizeof(st->st_dpd_seqno), (u_char *)&st->st_dpd_seqno);
|
||||
rng->destroy(rng);
|
||||
st->st_dpd_seqno &= 0x7fff;
|
||||
st->st_dpd_seqno++;
|
||||
}
|
||||
|
@ -5512,8 +5455,8 @@ dpd_inI_outR(struct state *st, struct isakmp_notification *const n, pb_stream *p
|
|||
/*
|
||||
* DPD out Responder
|
||||
*/
|
||||
stf_status
|
||||
dpd_inR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
|
||||
stf_status dpd_inR(struct state *st, struct isakmp_notification *const n,
|
||||
pb_stream *pbs)
|
||||
{
|
||||
u_int32_t seqno;
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include <freeswan.h>
|
||||
#include <ipsec_policy.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#ifdef KLIPS
|
||||
#include <signal.h>
|
||||
#include <sys/time.h> /* for select(2) */
|
||||
|
@ -42,7 +45,6 @@
|
|||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "rnd.h"
|
||||
#include "id.h"
|
||||
#include "connections.h"
|
||||
#include "state.h"
|
||||
|
@ -118,8 +120,7 @@ struct bare_shunt {
|
|||
static struct bare_shunt *bare_shunts = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
|
||||
static void DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
|
||||
{
|
||||
DBG(DBG_KLIPS,
|
||||
{
|
||||
|
@ -150,14 +151,12 @@ DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
|
|||
struct eroute_info *orphaned_holds = NULL;
|
||||
|
||||
/* forward declaration */
|
||||
static bool shunt_eroute(struct connection *c
|
||||
, struct spd_route *sr
|
||||
, enum routing_t rt_kind
|
||||
, unsigned int op, const char *opname);
|
||||
static void set_text_said(char *text_said
|
||||
, const ip_address *dst
|
||||
, ipsec_spi_t spi
|
||||
, int proto);
|
||||
static bool shunt_eroute(struct connection *c, struct spd_route *sr,
|
||||
enum routing_t rt_kind, unsigned int op,
|
||||
const char *opname);
|
||||
|
||||
static void set_text_said(char *text_said, const ip_address *dst,
|
||||
ipsec_spi_t spi, int proto);
|
||||
|
||||
bool no_klips = FALSE; /* don't actually use KLIPS */
|
||||
|
||||
|
@ -174,11 +173,9 @@ static const struct pfkey_proto_info null_proto_info[2] = {
|
|||
}
|
||||
};
|
||||
|
||||
void
|
||||
record_and_initiate_opportunistic(const ip_subnet *ours
|
||||
, const ip_subnet *his
|
||||
, int transport_proto
|
||||
, const char *why)
|
||||
void record_and_initiate_opportunistic(const ip_subnet *ours,
|
||||
const ip_subnet *his,
|
||||
int transport_proto, const char *why)
|
||||
{
|
||||
passert(samesubnettype(ours, his));
|
||||
|
||||
|
@ -279,25 +276,31 @@ static unsigned get_proto_reqid(unsigned base, int proto)
|
|||
* check if the number was previously used (assuming that no
|
||||
* SPI lives longer than 4G of its successors).
|
||||
*/
|
||||
ipsec_spi_t
|
||||
get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr, bool tunnel)
|
||||
ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr,
|
||||
bool tunnel)
|
||||
{
|
||||
static ipsec_spi_t spi = 0; /* host order, so not returned directly! */
|
||||
char text_said[SATOT_BUF];
|
||||
rng_t *rng;
|
||||
|
||||
set_text_said(text_said, &sr->this.host_addr, 0, proto);
|
||||
|
||||
if (kernel_ops->get_spi)
|
||||
{
|
||||
return kernel_ops->get_spi(&sr->that.host_addr
|
||||
, &sr->this.host_addr, proto, tunnel
|
||||
, get_proto_reqid(sr->reqid, proto)
|
||||
, IPSEC_DOI_SPI_OUR_MIN, 0xffffffff
|
||||
, text_said);
|
||||
}
|
||||
|
||||
spi++;
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
while (spi < IPSEC_DOI_SPI_OUR_MIN || spi == ntohl(avoid))
|
||||
get_rnd_bytes((u_char *)&spi, sizeof(spi));
|
||||
|
||||
{
|
||||
rng->get_bytes(rng, sizeof(spi), (u_char *)&spi);
|
||||
}
|
||||
rng->destroy(rng);
|
||||
DBG(DBG_CONTROL,
|
||||
{
|
||||
ipsec_spi_t spi_net = htonl(spi);
|
||||
|
@ -316,28 +319,30 @@ get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr, bool tunnel)
|
|||
* If we can't find one easily, return 0 (a bad SPI,
|
||||
* no matter what order) indicating failure.
|
||||
*/
|
||||
ipsec_spi_t
|
||||
get_my_cpi(struct spd_route *sr, bool tunnel)
|
||||
ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel)
|
||||
{
|
||||
static cpi_t
|
||||
first_busy_cpi = 0,
|
||||
latest_cpi;
|
||||
static cpi_t first_busy_cpi = 0, latest_cpi;
|
||||
char text_said[SATOT_BUF];
|
||||
rng_t *rng;
|
||||
|
||||
set_text_said(text_said, &sr->this.host_addr, 0, IPPROTO_COMP);
|
||||
|
||||
if (kernel_ops->get_spi)
|
||||
{
|
||||
return kernel_ops->get_spi(&sr->that.host_addr
|
||||
, &sr->this.host_addr, IPPROTO_COMP, tunnel
|
||||
, get_proto_reqid(sr->reqid, IPPROTO_COMP)
|
||||
, IPCOMP_FIRST_NEGOTIATED, IPCOMP_LAST_NEGOTIATED
|
||||
, text_said);
|
||||
}
|
||||
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
while (!(IPCOMP_FIRST_NEGOTIATED <= first_busy_cpi && first_busy_cpi < IPCOMP_LAST_NEGOTIATED))
|
||||
{
|
||||
get_rnd_bytes((u_char *)&first_busy_cpi, sizeof(first_busy_cpi));
|
||||
rng->get_bytes(rng, sizeof(first_busy_cpi), (u_char *)&first_busy_cpi);
|
||||
latest_cpi = first_busy_cpi;
|
||||
}
|
||||
rng->destroy(rng);
|
||||
|
||||
latest_cpi++;
|
||||
|
||||
|
@ -387,8 +392,8 @@ get_my_cpi(struct spd_route *sr, bool tunnel)
|
|||
# define DEFAULT_UPDOWN "ipsec _updown"
|
||||
#endif
|
||||
|
||||
static bool
|
||||
do_command(struct connection *c, struct spd_route *sr, const char *verb)
|
||||
static bool do_command(struct connection *c, struct spd_route *sr,
|
||||
const char *verb)
|
||||
{
|
||||
char cmd[1536]; /* arbitrary limit on shell command length */
|
||||
const char *verb_suffix;
|
||||
|
@ -647,8 +652,7 @@ enum routability {
|
|||
route_farconflict = 3
|
||||
};
|
||||
|
||||
static enum routability
|
||||
could_route(struct connection *c)
|
||||
static enum routability could_route(struct connection *c)
|
||||
{
|
||||
struct spd_route *esr, *rosr;
|
||||
struct connection *ero /* who, if anyone, owns our eroute? */
|
||||
|
@ -792,8 +796,7 @@ could_route(struct connection *c)
|
|||
return route_easy;
|
||||
}
|
||||
|
||||
bool
|
||||
trap_connection(struct connection *c)
|
||||
bool trap_connection(struct connection *c)
|
||||
{
|
||||
switch (could_route(c))
|
||||
{
|
||||
|
@ -818,9 +821,10 @@ trap_connection(struct connection *c)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* delete any eroute for a connection and unroute it if route isn't shared */
|
||||
void
|
||||
unroute_connection(struct connection *c)
|
||||
/**
|
||||
* Delete any eroute for a connection and unroute it if route isn't shared
|
||||
*/
|
||||
void unroute_connection(struct connection *c)
|
||||
{
|
||||
struct spd_route *sr;
|
||||
enum routing_t cr;
|
||||
|
@ -849,8 +853,8 @@ unroute_connection(struct connection *c)
|
|||
|
||||
#ifdef KLIPS
|
||||
|
||||
static void
|
||||
set_text_said(char *text_said, const ip_address *dst, ipsec_spi_t spi, int proto)
|
||||
static void set_text_said(char *text_said, const ip_address *dst,
|
||||
ipsec_spi_t spi, int proto)
|
||||
{
|
||||
ip_said said;
|
||||
|
||||
|
@ -862,8 +866,9 @@ set_text_said(char *text_said, const ip_address *dst, ipsec_spi_t spi, int proto
|
|||
* Trick: return a pointer to the pointer to the entry;
|
||||
* this allows the entry to be deleted.
|
||||
*/
|
||||
static struct bare_shunt **
|
||||
bare_shunt_ptr(const ip_subnet *ours, const ip_subnet *his, int transport_proto)
|
||||
static struct bare_shunt** bare_shunt_ptr(const ip_subnet *ours,
|
||||
const ip_subnet *his,
|
||||
int transport_proto)
|
||||
{
|
||||
struct bare_shunt *p, **pp;
|
||||
|
||||
|
@ -880,8 +885,7 @@ bare_shunt_ptr(const ip_subnet *ours, const ip_subnet *his, int transport_proto)
|
|||
}
|
||||
|
||||
/* free a bare_shunt entry, given a pointer to the pointer */
|
||||
static void
|
||||
free_bare_shunt(struct bare_shunt **pp)
|
||||
static void free_bare_shunt(struct bare_shunt **pp)
|
||||
{
|
||||
if (pp == NULL)
|
||||
{
|
||||
|
@ -933,19 +937,18 @@ show_shunt_status(void)
|
|||
* op is one of the ERO_* operators.
|
||||
*/
|
||||
|
||||
static bool
|
||||
raw_eroute(const ip_address *this_host
|
||||
, const ip_subnet *this_client
|
||||
, const ip_address *that_host
|
||||
, const ip_subnet *that_client
|
||||
, ipsec_spi_t spi
|
||||
, unsigned int proto
|
||||
, unsigned int satype
|
||||
, unsigned int transport_proto
|
||||
, const struct pfkey_proto_info *proto_info
|
||||
, time_t use_lifetime
|
||||
, unsigned int op
|
||||
, const char *opname USED_BY_DEBUG)
|
||||
static bool raw_eroute(const ip_address *this_host,
|
||||
const ip_subnet *this_client,
|
||||
const ip_address *that_host,
|
||||
const ip_subnet *that_client,
|
||||
ipsec_spi_t spi,
|
||||
unsigned int proto,
|
||||
unsigned int satype,
|
||||
unsigned int transport_proto,
|
||||
const struct pfkey_proto_info *proto_info,
|
||||
time_t use_lifetime,
|
||||
unsigned int op,
|
||||
const char *opname USED_BY_DEBUG)
|
||||
{
|
||||
char text_said[SATOT_BUF];
|
||||
|
||||
|
@ -971,8 +974,8 @@ raw_eroute(const ip_address *this_host
|
|||
}
|
||||
|
||||
/* test to see if %hold remains */
|
||||
bool
|
||||
has_bare_hold(const ip_address *src, const ip_address *dst, int transport_proto)
|
||||
bool has_bare_hold(const ip_address *src, const ip_address *dst,
|
||||
int transport_proto)
|
||||
{
|
||||
ip_subnet this_client, that_client;
|
||||
struct bare_shunt **bspp;
|
||||
|
@ -989,13 +992,9 @@ has_bare_hold(const ip_address *src, const ip_address *dst, int transport_proto)
|
|||
/* Replace (or delete) a shunt that is in the bare_shunts table.
|
||||
* Issues the PF_KEY commands and updates the bare_shunts table.
|
||||
*/
|
||||
bool
|
||||
replace_bare_shunt(const ip_address *src, const ip_address *dst
|
||||
, policy_prio_t policy_prio
|
||||
, ipsec_spi_t shunt_spi /* in host order! */
|
||||
, bool repl /* if TRUE, replace; if FALSE, delete */
|
||||
, unsigned int transport_proto
|
||||
, const char *why)
|
||||
bool replace_bare_shunt(const ip_address *src, const ip_address *dst,
|
||||
policy_prio_t policy_prio, ipsec_spi_t shunt_spi,
|
||||
bool repl, unsigned int transport_proto, const char *why)
|
||||
{
|
||||
ip_subnet this_client, that_client;
|
||||
ip_subnet this_broad_client, that_broad_client;
|
||||
|
@ -1060,11 +1059,10 @@ replace_bare_shunt(const ip_address *src, const ip_address *dst
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
eroute_connection(struct spd_route *sr
|
||||
, ipsec_spi_t spi, unsigned int proto, unsigned int satype
|
||||
, const struct pfkey_proto_info *proto_info
|
||||
, unsigned int op, const char *opname)
|
||||
static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
|
||||
unsigned int proto, unsigned int satype,
|
||||
const struct pfkey_proto_info *proto_info,
|
||||
unsigned int op, const char *opname)
|
||||
{
|
||||
const ip_address *peer = &sr->that.host_addr;
|
||||
char buf2[256];
|
||||
|
@ -1084,11 +1082,10 @@ eroute_connection(struct spd_route *sr
|
|||
|
||||
/* assign a bare hold to a connection */
|
||||
|
||||
bool
|
||||
assign_hold(struct connection *c USED_BY_DEBUG
|
||||
, struct spd_route *sr
|
||||
, int transport_proto
|
||||
, const ip_address *src, const ip_address *dst)
|
||||
bool assign_hold(struct connection *c USED_BY_DEBUG, struct spd_route *sr,
|
||||
int transport_proto,
|
||||
const ip_address *src,
|
||||
const ip_address *dst)
|
||||
{
|
||||
/* either the automatically installed %hold eroute is broad enough
|
||||
* or we try to add a broader one and delete the automatic one.
|
||||
|
@ -1143,9 +1140,8 @@ assign_hold(struct connection *c USED_BY_DEBUG
|
|||
}
|
||||
|
||||
/* install or remove eroute for SA Group */
|
||||
static bool
|
||||
sag_eroute(struct state *st, struct spd_route *sr
|
||||
, unsigned op, const char *opname)
|
||||
static bool sag_eroute(struct state *st, struct spd_route *sr,
|
||||
unsigned op, const char *opname)
|
||||
{
|
||||
u_int inner_proto = 0;
|
||||
u_int inner_satype = 0;
|
||||
|
@ -1259,11 +1255,9 @@ shunt_policy_spi(struct connection *c, bool prospective)
|
|||
* If negotiation has failed, the choice between %trap/%pass/%drop/%reject
|
||||
* is specified in the policy of connection c.
|
||||
*/
|
||||
static bool
|
||||
shunt_eroute(struct connection *c
|
||||
, struct spd_route *sr
|
||||
, enum routing_t rt_kind
|
||||
, unsigned int op, const char *opname)
|
||||
static bool shunt_eroute(struct connection *c, struct spd_route *sr,
|
||||
enum routing_t rt_kind,
|
||||
unsigned int op, const char *opname)
|
||||
{
|
||||
/* We are constructing a special SAID for the eroute.
|
||||
* The destination doesn't seem to matter, but the family does.
|
||||
|
@ -1355,8 +1349,7 @@ shunt_eroute(struct connection *c
|
|||
* The task here is to remove the ":p" part so that the rest can be read
|
||||
* by another routine.
|
||||
*/
|
||||
static const char *
|
||||
read_proto(const char * s, size_t * len, int * transport_proto)
|
||||
static const char *read_proto(const char * s, size_t * len, int * transport_proto)
|
||||
{
|
||||
const char * p;
|
||||
const char * ugh;
|
||||
|
@ -1405,8 +1398,7 @@ read_proto(const char * s, size_t * len, int * transport_proto)
|
|||
* searching for each is sequential. If this becomes a problem, faster
|
||||
* searches could be implemented (hash or radix tree, for example).
|
||||
*/
|
||||
void
|
||||
scan_proc_shunts(void)
|
||||
void scan_proc_shunts(void)
|
||||
{
|
||||
static const char procname[] = "/proc/net/ipsec_eroute";
|
||||
FILE *f;
|
||||
|
@ -1645,9 +1637,8 @@ scan_proc_shunts(void)
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
del_spi(ipsec_spi_t spi, int proto
|
||||
, const ip_address *src, const ip_address *dest)
|
||||
static bool del_spi(ipsec_spi_t spi, int proto,
|
||||
const ip_address *src, const ip_address *dest)
|
||||
{
|
||||
char text_said[SATOT_BUF];
|
||||
struct kernel_sa sa;
|
||||
|
@ -1670,8 +1661,7 @@ del_spi(ipsec_spi_t spi, int proto
|
|||
* ipsec-0.5.
|
||||
*/
|
||||
|
||||
static bool
|
||||
setup_half_ipsec_sa(struct state *st, bool inbound)
|
||||
static bool setup_half_ipsec_sa(struct state *st, bool inbound)
|
||||
{
|
||||
/* Build an inbound or outbound SA */
|
||||
|
||||
|
@ -2122,8 +2112,7 @@ fail:
|
|||
|
||||
/* teardown_ipsec_sa is a canibalized version of setup_ipsec_sa */
|
||||
|
||||
static bool
|
||||
teardown_half_ipsec_sa(struct state *st, bool inbound)
|
||||
static bool teardown_half_ipsec_sa(struct state *st, bool inbound)
|
||||
{
|
||||
/* We need to delete AH, ESP, and IP in IP SPIs.
|
||||
* But if there is more than one, they have been grouped
|
||||
|
@ -2218,8 +2207,7 @@ teardown_half_ipsec_sa(struct state *st, bool inbound)
|
|||
/*
|
||||
* get information about a given sa
|
||||
*/
|
||||
bool
|
||||
get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
|
||||
bool get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
|
||||
{
|
||||
char text_said[SATOT_BUF];
|
||||
struct kernel_sa sa;
|
||||
|
@ -2290,8 +2278,7 @@ const struct kernel_ops *kernel_ops;
|
|||
|
||||
#endif /* KLIPS */
|
||||
|
||||
void
|
||||
init_kernel(void)
|
||||
void init_kernel(void)
|
||||
{
|
||||
#ifdef KLIPS
|
||||
|
||||
|
@ -2343,8 +2330,7 @@ init_kernel(void)
|
|||
* The Responder will subsequently use install_ipsec_sa for the outbound.
|
||||
* The Initiator uses install_ipsec_sa to install both at once.
|
||||
*/
|
||||
bool
|
||||
install_inbound_ipsec_sa(struct state *st)
|
||||
bool install_inbound_ipsec_sa(struct state *st)
|
||||
{
|
||||
struct connection *const c = st->st_connection;
|
||||
|
||||
|
@ -2405,10 +2391,9 @@ install_inbound_ipsec_sa(struct state *st)
|
|||
* Any SA Group must have already been created.
|
||||
* On failure, steps will be unwound.
|
||||
*/
|
||||
bool
|
||||
route_and_eroute(struct connection *c USED_BY_KLIPS
|
||||
, struct spd_route *sr USED_BY_KLIPS
|
||||
, struct state *st USED_BY_KLIPS)
|
||||
bool route_and_eroute(struct connection *c USED_BY_KLIPS,
|
||||
struct spd_route *sr USED_BY_KLIPS,
|
||||
struct state *st USED_BY_KLIPS)
|
||||
{
|
||||
#ifdef KLIPS
|
||||
struct spd_route *esr;
|
||||
|
@ -2688,8 +2673,7 @@ route_and_eroute(struct connection *c USED_BY_KLIPS
|
|||
#endif /* !KLIPS */
|
||||
}
|
||||
|
||||
bool
|
||||
install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
|
||||
bool install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
|
||||
{
|
||||
#ifdef KLIPS
|
||||
struct spd_route *sr;
|
||||
|
@ -2764,8 +2748,8 @@ install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
|
|||
* we may not succeed, but we bull ahead anyway because
|
||||
* we cannot do anything better by recognizing failure
|
||||
*/
|
||||
void
|
||||
delete_ipsec_sa(struct state *st USED_BY_KLIPS, bool inbound_only USED_BY_KLIPS)
|
||||
void delete_ipsec_sa(struct state *st USED_BY_KLIPS,
|
||||
bool inbound_only USED_BY_KLIPS)
|
||||
{
|
||||
#ifdef KLIPS
|
||||
if (!inbound_only)
|
||||
|
@ -2888,8 +2872,7 @@ bool update_ipsec_sa (struct state *st USED_BY_KLIPS)
|
|||
* If FALSE, DPD is not necessary. We also return TRUE for errors, as they
|
||||
* could mean that the SA is broken and needs to be replace anyway.
|
||||
*/
|
||||
bool
|
||||
was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
|
||||
bool was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
|
||||
{
|
||||
static const char procname[] = "/proc/net/ipsec_spi";
|
||||
FILE *f;
|
||||
|
|
|
@ -24,9 +24,11 @@
|
|||
#include <freeswan.h>
|
||||
#include <ipsec_policy.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/asn1_parser.h>
|
||||
#include <asn1/oid.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
|
@ -34,7 +36,6 @@
|
|||
#include "x509.h"
|
||||
#include "crl.h"
|
||||
#include "ca.h"
|
||||
#include "rnd.h"
|
||||
#include "certs.h"
|
||||
#include "smartcard.h"
|
||||
#include "whack.h"
|
||||
|
@ -884,10 +885,14 @@ static chunk_t build_requestor_name(void)
|
|||
*/
|
||||
static chunk_t build_nonce_extension(ocsp_location_t *location)
|
||||
{
|
||||
rng_t *rng;
|
||||
|
||||
/* generate a random nonce */
|
||||
location->nonce.ptr = malloc(NONCE_LENGTH),
|
||||
location->nonce.len = NONCE_LENGTH;
|
||||
get_rnd_bytes(location->nonce.ptr, NONCE_LENGTH);
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
|
||||
rng->get_bytes(rng, location->nonce.len, location->nonce.ptr);
|
||||
rng->destroy(rng);
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
||||
, ASN1_nonce_oid
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
#include <freeswan.h>
|
||||
#include <libsha2/sha2.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/asn1_parser.h>
|
||||
#include <asn1/oid.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
|
@ -33,7 +35,6 @@
|
|||
#include "md2.h"
|
||||
#include "md5.h"
|
||||
#include "sha1.h"
|
||||
#include "rnd.h"
|
||||
|
||||
const struct fld RSA_private_field[] =
|
||||
{
|
||||
|
@ -430,6 +431,7 @@ chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
|
|||
u_char *pos = padded;
|
||||
int padding = key->k - in.len - 3;
|
||||
int i;
|
||||
rng_t *rng;
|
||||
|
||||
if (padding < 8 || key->k > RSA_MAX_OCTETS)
|
||||
return chunk_empty;
|
||||
|
@ -439,15 +441,17 @@ chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
|
|||
*pos++ = 0x02;
|
||||
|
||||
/* pad with pseudo random bytes unequal to zero */
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
for (i = 0; i < padding; i++)
|
||||
{
|
||||
get_rnd_bytes(pos, padding);
|
||||
rng->get_bytes(rng, padding, pos);
|
||||
while (!*pos)
|
||||
{
|
||||
get_rnd_bytes(pos, 1);
|
||||
rng->get_bytes(rng, 1, pos);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
rng->destroy(rng);
|
||||
|
||||
/* append the padding terminator */
|
||||
*pos++ = 0x00;
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/asn1_parser.h>
|
||||
#include <asn1/oid.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
|
@ -30,7 +32,6 @@
|
|||
#include "x509.h"
|
||||
#include "certs.h"
|
||||
#include "pkcs7.h"
|
||||
#include "rnd.h"
|
||||
|
||||
const contentInfo_t empty_contentInfo = {
|
||||
OID_UNKNOWN , /* type */
|
||||
|
@ -744,6 +745,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int ciph
|
|||
chunk_t out;
|
||||
chunk_t cipher_oid;
|
||||
|
||||
rng_t *rng;
|
||||
u_int total_keys, i;
|
||||
size_t padding = pad_up(data.len, DES_CBC_BLOCK_SIZE);
|
||||
|
||||
|
@ -789,16 +791,19 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int ciph
|
|||
)
|
||||
|
||||
/* generate a strong random key for DES/3DES */
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
|
||||
des_check_key_save = des_check_key;
|
||||
des_check_key = TRUE;
|
||||
for (i = 0; i < total_keys;i++)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
get_rnd_bytes((char*)key[i], DES_CBC_BLOCK_SIZE);
|
||||
rng->get_bytes(rng, DES_CBC_BLOCK_SIZE, (char*)key[i]);
|
||||
des_set_odd_parity(&key[i]);
|
||||
if (!des_set_key(&key[i], ks[i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
plog("weak DES key discarded - we try again");
|
||||
}
|
||||
DBG(DBG_PRIVATE,
|
||||
|
@ -808,11 +813,12 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int ciph
|
|||
des_check_key = des_check_key_save;
|
||||
|
||||
/* generate an iv for DES/3DES CBC */
|
||||
get_rnd_bytes(des_iv, DES_CBC_BLOCK_SIZE);
|
||||
rng->get_bytes(rng, DES_CBC_BLOCK_SIZE, des_iv);
|
||||
memcpy(iv.ptr, des_iv, DES_CBC_BLOCK_SIZE);
|
||||
DBG(DBG_RAW,
|
||||
DBG_dump_chunk("DES IV :", iv)
|
||||
)
|
||||
rng->destroy(rng);
|
||||
|
||||
/* encryption using specified cipher */
|
||||
switch (cipher)
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#include "keys.h"
|
||||
#include "adns.h" /* needs <resolv.h> */
|
||||
#include "dnskey.h" /* needs keys.h and adns.h */
|
||||
#include "rnd.h"
|
||||
#include "state.h"
|
||||
#include "ipsec_doi.h" /* needs demux.h and state.h */
|
||||
#include "ocsp.h"
|
||||
|
@ -73,6 +72,7 @@
|
|||
#include "nat_traversal.h"
|
||||
#include "virtual.h"
|
||||
#include "timer.h"
|
||||
#include "vendor.h"
|
||||
|
||||
static void usage(const char *mess)
|
||||
{
|
||||
|
@ -634,9 +634,8 @@ int main(int argc, char **argv)
|
|||
|
||||
init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
|
||||
init_virtual_ip(virtual_private);
|
||||
scx_init(pkcs11_module_path, pkcs11_init_args); /* load and initialize PKCS #11 module */
|
||||
xauth_init(); /* load and initialize XAUTH module */
|
||||
init_rnd_pool();
|
||||
scx_init(pkcs11_module_path, pkcs11_init_args);
|
||||
xauth_init();
|
||||
init_secret();
|
||||
init_states();
|
||||
init_crypto();
|
||||
|
|
|
@ -1,593 +0,0 @@
|
|||
/* primegen.c - prime number generator
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG 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.
|
||||
*
|
||||
* GnuPG 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
|
||||
*
|
||||
* ***********************************************************************
|
||||
* The algorithm used to generate practically save primes is due to
|
||||
* Lim and Lee as described in the CRYPTO '97 proceedings (ISBN3540633847)
|
||||
* page 260.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef PLUTO
|
||||
#include <gmp.h>
|
||||
#include <freeswan.h>
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "log.h"
|
||||
#include "rnd.h"
|
||||
#include "gcryptfix.h"
|
||||
#else /*! PLUTO */
|
||||
/* #include <assert.h> */
|
||||
/* #include <config.h> */
|
||||
/* #include "util.h" */
|
||||
/* #include "mpi.h" */
|
||||
/* #include "cipher.h" */
|
||||
#endif /* !PLUTO */
|
||||
|
||||
static int no_of_small_prime_numbers;
|
||||
static MPI gen_prime( unsigned nbits, int mode, int randomlevel );
|
||||
static int check_prime( MPI prime, MPI val_2 );
|
||||
static int is_prime( MPI n, unsigned steps, int *count );
|
||||
static void m_out_of_n( char *array, int m, int n );
|
||||
|
||||
|
||||
static void
|
||||
progress( int c )
|
||||
{
|
||||
fputc( c, stderr );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a prime number (stored in secure memory)
|
||||
*/
|
||||
MPI
|
||||
generate_secret_prime( unsigned nbits )
|
||||
{
|
||||
MPI prime;
|
||||
|
||||
prime = gen_prime( nbits, 1, 2 );
|
||||
progress('\n');
|
||||
return prime;
|
||||
}
|
||||
|
||||
MPI
|
||||
generate_public_prime( unsigned nbits )
|
||||
{
|
||||
MPI prime;
|
||||
|
||||
prime = gen_prime( nbits, 0, 2 );
|
||||
progress('\n');
|
||||
return prime;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* We do not need to use the strongest RNG because we gain no extra
|
||||
* security from it - The prime number is public and we could also
|
||||
* offer the factors for those who are willing to check that it is
|
||||
* indeed a strong prime.
|
||||
*
|
||||
* mode 0: Standard
|
||||
* 1: Make sure that at least one factor is of size qbits.
|
||||
*/
|
||||
MPI
|
||||
generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
||||
MPI g, MPI **ret_factors )
|
||||
{
|
||||
int n; /* number of factors */
|
||||
int m; /* number of primes in pool */
|
||||
unsigned fbits; /* length of prime factors */
|
||||
MPI *factors; /* current factors */
|
||||
MPI *pool; /* pool of primes */
|
||||
MPI q; /* first prime factor (variable)*/
|
||||
MPI prime; /* prime test value */
|
||||
MPI q_factor; /* used for mode 1 */
|
||||
byte *perms = NULL;
|
||||
int i, j;
|
||||
int count1, count2;
|
||||
unsigned nprime;
|
||||
unsigned req_qbits = qbits; /* the requested q bits size */
|
||||
MPI val_2 = mpi_alloc_set_ui( 2 );
|
||||
|
||||
/* find number of needed prime factors */
|
||||
for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
|
||||
;
|
||||
n--;
|
||||
if( !n || (mode==1 && n < 2) )
|
||||
log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
|
||||
if( mode == 1 ) {
|
||||
n--;
|
||||
fbits = (pbits - 2*req_qbits -1) / n;
|
||||
qbits = pbits - req_qbits - n*fbits;
|
||||
}
|
||||
else {
|
||||
fbits = (pbits - req_qbits -1) / n;
|
||||
qbits = pbits - n*fbits;
|
||||
}
|
||||
if( DBG_CIPHER )
|
||||
log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
|
||||
pbits, req_qbits, qbits, fbits, n );
|
||||
prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
|
||||
q = gen_prime( qbits, 0, 1 );
|
||||
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
|
||||
|
||||
/* allocate an array to hold the factors + 2 for later usage */
|
||||
#ifdef PLUTO
|
||||
m_alloc_ptrs_clear(factors, n+2);
|
||||
#else
|
||||
factors = m_alloc_clear( (n+2) * sizeof *factors );
|
||||
#endif
|
||||
|
||||
/* make a pool of 3n+5 primes (this is an arbitrary value) */
|
||||
m = n*3+5;
|
||||
if( mode == 1 )
|
||||
m += 5; /* need some more for DSA */
|
||||
if( m < 25 )
|
||||
m = 25;
|
||||
#ifdef PLUTO
|
||||
m_alloc_ptrs_clear(pool, m);
|
||||
#else
|
||||
pool = m_alloc_clear( m * sizeof *pool );
|
||||
#endif
|
||||
|
||||
/* permutate over the pool of primes */
|
||||
count1=count2=0;
|
||||
do {
|
||||
next_try:
|
||||
if( !perms ) {
|
||||
/* allocate new primes */
|
||||
for(i=0; i < m; i++ ) {
|
||||
mpi_free(pool[i]);
|
||||
pool[i] = NULL;
|
||||
}
|
||||
/* init m_out_of_n() */
|
||||
#ifdef PLUTO
|
||||
perms = malloc(m);
|
||||
#else
|
||||
perms = m_alloc_clear( m );
|
||||
#endif
|
||||
for(i=0; i < n; i++ ) {
|
||||
perms[i] = 1;
|
||||
pool[i] = gen_prime( fbits, 0, 1 );
|
||||
factors[i] = pool[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_out_of_n( perms, n, m );
|
||||
for(i=j=0; i < m && j < n ; i++ )
|
||||
if( perms[i] ) {
|
||||
if( !pool[i] )
|
||||
pool[i] = gen_prime( fbits, 0, 1 );
|
||||
factors[j++] = pool[i];
|
||||
}
|
||||
if( i == n ) {
|
||||
m_free(perms); perms = NULL;
|
||||
progress('!');
|
||||
goto next_try; /* allocate new primes */
|
||||
}
|
||||
}
|
||||
|
||||
mpi_set( prime, q );
|
||||
mpi_mul_ui( prime, prime, 2 );
|
||||
if( mode == 1 )
|
||||
mpi_mul( prime, prime, q_factor );
|
||||
for(i=0; i < n; i++ )
|
||||
mpi_mul( prime, prime, factors[i] );
|
||||
mpi_add_ui( prime, prime, 1 );
|
||||
nprime = mpi_get_nbits(prime);
|
||||
if( nprime < pbits ) {
|
||||
if( ++count1 > 20 ) {
|
||||
count1 = 0;
|
||||
qbits++;
|
||||
progress('>');
|
||||
q = gen_prime( qbits, 0, 1 );
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
else
|
||||
count1 = 0;
|
||||
if( nprime > pbits ) {
|
||||
if( ++count2 > 20 ) {
|
||||
count2 = 0;
|
||||
qbits--;
|
||||
progress('<');
|
||||
q = gen_prime( qbits, 0, 1 );
|
||||
goto next_try;
|
||||
}
|
||||
}
|
||||
else
|
||||
count2 = 0;
|
||||
} while( !(nprime == pbits && check_prime( prime, val_2 )) );
|
||||
|
||||
if( DBG_CIPHER ) {
|
||||
progress('\n');
|
||||
log_mpidump( "prime : ", prime );
|
||||
log_mpidump( "factor q: ", q );
|
||||
if( mode == 1 )
|
||||
log_mpidump( "factor q0: ", q_factor );
|
||||
for(i=0; i < n; i++ )
|
||||
log_mpidump( "factor pi: ", factors[i] );
|
||||
log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
|
||||
if( mode == 1 )
|
||||
fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
|
||||
for(i=0; i < n; i++ )
|
||||
fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
|
||||
progress('\n');
|
||||
}
|
||||
|
||||
if( ret_factors ) { /* caller wants the factors */
|
||||
#ifdef PLUTO
|
||||
m_alloc_ptrs_clear(*ret_factors, n+2);
|
||||
#else
|
||||
*ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
|
||||
#endif
|
||||
if( mode == 1 ) {
|
||||
i = 0;
|
||||
(*ret_factors)[i++] = mpi_copy( q_factor );
|
||||
for(; i <= n; i++ )
|
||||
(*ret_factors)[i] = mpi_copy( factors[i] );
|
||||
}
|
||||
else {
|
||||
for(; i < n; i++ )
|
||||
(*ret_factors)[i] = mpi_copy( factors[i] );
|
||||
}
|
||||
}
|
||||
|
||||
if( g ) { /* create a generator (start with 3)*/
|
||||
MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
|
||||
MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
|
||||
MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
|
||||
|
||||
if( mode == 1 )
|
||||
BUG(); /* not yet implemented */
|
||||
factors[n] = q;
|
||||
factors[n+1] = mpi_alloc_set_ui(2);
|
||||
mpi_sub_ui( pmin1, prime, 1 );
|
||||
mpi_set_ui(g,2);
|
||||
do {
|
||||
mpi_add_ui(g, g, 1);
|
||||
if( DBG_CIPHER ) {
|
||||
#ifdef PLUTO
|
||||
log_mpidump("checking g: ", g);
|
||||
#else
|
||||
log_debug("checking g: ");
|
||||
mpi_print( stderr, g, 1 );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
progress('^');
|
||||
for(i=0; i < n+2; i++ ) {
|
||||
/*fputc('~', stderr);*/
|
||||
mpi_fdiv_q(tmp, pmin1, factors[i] );
|
||||
/* (no mpi_pow(), but it is okay to use this with mod prime) */
|
||||
mpi_powm(b, g, tmp, prime );
|
||||
if( !mpi_cmp_ui(b, 1) )
|
||||
break;
|
||||
}
|
||||
if( DBG_CIPHER )
|
||||
progress('\n');
|
||||
} while( i < n+2 );
|
||||
mpi_free(factors[n+1]);
|
||||
mpi_free(tmp);
|
||||
mpi_free(b);
|
||||
mpi_free(pmin1);
|
||||
}
|
||||
if( !DBG_CIPHER )
|
||||
progress('\n');
|
||||
|
||||
m_free( factors ); /* (factors are shallow copies) */
|
||||
for(i=0; i < m; i++ )
|
||||
mpi_free( pool[i] );
|
||||
m_free( pool );
|
||||
m_free(perms);
|
||||
mpi_free(val_2);
|
||||
return prime;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static MPI
|
||||
gen_prime( unsigned nbits, int secret, int randomlevel )
|
||||
{
|
||||
unsigned nlimbs;
|
||||
MPI prime, ptest, pminus1, val_2, val_3, result;
|
||||
int i;
|
||||
unsigned x, step;
|
||||
unsigned count1, count2;
|
||||
int *mods;
|
||||
|
||||
if( 0 && DBG_CIPHER )
|
||||
log_debug("generate a prime of %u bits ", nbits );
|
||||
|
||||
if( !no_of_small_prime_numbers ) {
|
||||
for(i=0; small_prime_numbers[i]; i++ )
|
||||
no_of_small_prime_numbers++;
|
||||
}
|
||||
mods = m_alloc( no_of_small_prime_numbers * sizeof *mods );
|
||||
/* make nbits fit into MPI implementation */
|
||||
nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB;
|
||||
val_2 = mpi_alloc_set_ui( 2 );
|
||||
val_3 = mpi_alloc_set_ui( 3);
|
||||
prime = secret? mpi_alloc_secure( nlimbs ): mpi_alloc( nlimbs );
|
||||
result = mpi_alloc_like( prime );
|
||||
pminus1= mpi_alloc_like( prime );
|
||||
ptest = mpi_alloc_like( prime );
|
||||
count1 = count2 = 0;
|
||||
for(;;) { /* try forvever */
|
||||
int dotcount=0;
|
||||
|
||||
/* generate a random number */
|
||||
{ char *p = get_random_bits( nbits, randomlevel, secret );
|
||||
mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
/* set high order bit to 1, set low order bit to 1 */
|
||||
mpi_set_highbit( prime, nbits-1 );
|
||||
mpi_set_bit( prime, 0 );
|
||||
|
||||
/* calculate all remainders */
|
||||
for(i=0; (x = small_prime_numbers[i]); i++ )
|
||||
mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
|
||||
|
||||
/* now try some primes starting with prime */
|
||||
for(step=0; step < 20000; step += 2 ) {
|
||||
/* check against all the small primes we have in mods */
|
||||
count1++;
|
||||
for(i=0; (x = small_prime_numbers[i]); i++ ) {
|
||||
while( mods[i] + step >= x )
|
||||
mods[i] -= x;
|
||||
if( !(mods[i] + step) )
|
||||
break;
|
||||
}
|
||||
if( x )
|
||||
continue; /* found a multiple of an already known prime */
|
||||
|
||||
mpi_add_ui( ptest, prime, step );
|
||||
|
||||
/* do a faster Fermat test */
|
||||
count2++;
|
||||
mpi_sub_ui( pminus1, ptest, 1);
|
||||
mpi_powm( result, val_2, pminus1, ptest );
|
||||
if( !mpi_cmp_ui( result, 1 ) ) { /* not composite */
|
||||
/* perform stronger tests */
|
||||
if( is_prime(ptest, 5, &count2 ) ) {
|
||||
if( !mpi_test_bit( ptest, nbits-1 ) ) {
|
||||
progress('\n');
|
||||
log_debug("overflow in prime generation\n");
|
||||
break; /* step loop, continue with a new prime */
|
||||
}
|
||||
|
||||
mpi_free(val_2);
|
||||
mpi_free(val_3);
|
||||
mpi_free(result);
|
||||
mpi_free(pminus1);
|
||||
mpi_free(prime);
|
||||
m_free(mods);
|
||||
return ptest;
|
||||
}
|
||||
}
|
||||
if( ++dotcount == 10 ) {
|
||||
progress('.');
|
||||
dotcount = 0;
|
||||
}
|
||||
}
|
||||
progress(':'); /* restart with a new random value */
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* Returns: true if this may be a prime
|
||||
*/
|
||||
static int
|
||||
check_prime( MPI prime, MPI val_2 )
|
||||
{
|
||||
int i;
|
||||
unsigned x;
|
||||
int count=0;
|
||||
|
||||
/* check against small primes */
|
||||
for(i=0; (x = small_prime_numbers[i]); i++ ) {
|
||||
if( mpi_divisible_ui( prime, x ) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a quick fermat test */
|
||||
{
|
||||
MPI result = mpi_alloc_like( prime );
|
||||
MPI pminus1 = mpi_alloc_like( prime );
|
||||
mpi_sub_ui( pminus1, prime, 1);
|
||||
mpi_powm( result, val_2, pminus1, prime );
|
||||
mpi_free( pminus1 );
|
||||
if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
|
||||
mpi_free( result );
|
||||
progress('.');
|
||||
return 0;
|
||||
}
|
||||
mpi_free( result );
|
||||
}
|
||||
|
||||
/* perform stronger tests */
|
||||
if( is_prime(prime, 5, &count ) )
|
||||
return 1; /* is probably a prime */
|
||||
progress('.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return true if n is probably a prime
|
||||
*/
|
||||
static int
|
||||
is_prime( MPI n, unsigned steps, int *count )
|
||||
{
|
||||
MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
|
||||
MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
|
||||
MPI z = mpi_alloc( mpi_get_nlimbs( n ) );
|
||||
MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
|
||||
MPI a2 = mpi_alloc_set_ui( 2 );
|
||||
MPI q;
|
||||
unsigned i, j, k;
|
||||
int rc = 0;
|
||||
unsigned nbits = mpi_get_nbits( n );
|
||||
|
||||
mpi_sub_ui( nminus1, n, 1 );
|
||||
|
||||
/* find q and k, so that n = 1 + 2^k * q */
|
||||
q = mpi_copy( nminus1 );
|
||||
k = mpi_trailing_zeros( q );
|
||||
mpi_tdiv_q_2exp(q, q, k);
|
||||
|
||||
for(i=0 ; i < steps; i++ ) {
|
||||
++*count;
|
||||
if( !i ) {
|
||||
mpi_set_ui( x, 2 );
|
||||
}
|
||||
else {
|
||||
/*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/
|
||||
{ char *p = get_random_bits( nbits, 0, 0 );
|
||||
mpi_set_buffer( x, p, (nbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
}
|
||||
/* make sure that the number is smaller than the prime
|
||||
* and keep the randomness of the high bit */
|
||||
if( mpi_test_bit( x, nbits-2 ) ) {
|
||||
mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */
|
||||
}
|
||||
else {
|
||||
mpi_set_highbit( x, nbits-2 );
|
||||
mpi_clear_bit( x, nbits-2 );
|
||||
}
|
||||
assert( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
|
||||
}
|
||||
mpi_powm( y, x, q, n);
|
||||
if( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) ) {
|
||||
for( j=1; j < k && mpi_cmp( y, nminus1 ); j++ ) {
|
||||
mpi_powm(y, y, a2, n);
|
||||
if( !mpi_cmp_ui( y, 1 ) )
|
||||
goto leave; /* not a prime */
|
||||
}
|
||||
if( mpi_cmp( y, nminus1 ) )
|
||||
goto leave; /* not a prime */
|
||||
}
|
||||
progress('+');
|
||||
}
|
||||
rc = 1; /* may be a prime */
|
||||
|
||||
leave:
|
||||
mpi_free( x );
|
||||
mpi_free( y );
|
||||
mpi_free( z );
|
||||
mpi_free( nminus1 );
|
||||
mpi_free( q );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
m_out_of_n( char *array, int m, int n )
|
||||
{
|
||||
int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
|
||||
|
||||
if( !m || m >= n )
|
||||
return;
|
||||
|
||||
if( m == 1 ) { /* special case */
|
||||
for(i=0; i < n; i++ )
|
||||
if( array[i] ) {
|
||||
array[i++] = 0;
|
||||
if( i >= n )
|
||||
i = 0;
|
||||
array[i] = 1;
|
||||
return;
|
||||
}
|
||||
BUG();
|
||||
}
|
||||
|
||||
for(j=1; j < n; j++ ) {
|
||||
if( array[n-1] == array[n-j-1] )
|
||||
continue;
|
||||
j1 = j;
|
||||
break;
|
||||
}
|
||||
|
||||
if( m & 1 ) { /* m is odd */
|
||||
if( array[n-1] ) {
|
||||
if( j1 & 1 ) {
|
||||
k1 = n - j1;
|
||||
k2 = k1+2;
|
||||
if( k2 > n )
|
||||
k2 = n;
|
||||
goto leave;
|
||||
}
|
||||
goto scan;
|
||||
}
|
||||
k2 = n - j1 - 1;
|
||||
if( k2 == 0 ) {
|
||||
k1 = i;
|
||||
k2 = n - j1;
|
||||
}
|
||||
else if( array[k2] && array[k2-1] )
|
||||
k1 = n;
|
||||
else
|
||||
k1 = k2 + 1;
|
||||
}
|
||||
else { /* m is even */
|
||||
if( !array[n-1] ) {
|
||||
k1 = n - j1;
|
||||
k2 = k1 + 1;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( !(j1 & 1) ) {
|
||||
k1 = n - j1;
|
||||
k2 = k1+2;
|
||||
if( k2 > n )
|
||||
k2 = n;
|
||||
goto leave;
|
||||
}
|
||||
scan:
|
||||
jp = n - j1 - 1;
|
||||
for(i=1; i <= jp; i++ ) {
|
||||
i1 = jp + 2 - i;
|
||||
if( array[i1-1] ) {
|
||||
if( array[i1-2] ) {
|
||||
k1 = i1 - 1;
|
||||
k2 = n - j1;
|
||||
}
|
||||
else {
|
||||
k1 = i1 - 1;
|
||||
k2 = n + 1 - j1;
|
||||
}
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
k1 = 1;
|
||||
k2 = n + 1 - m;
|
||||
}
|
||||
leave:
|
||||
array[k1-1] = !array[k1-1];
|
||||
array[k2-1] = !array[k2-1];
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/* smallprime.c - List of small primes
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG 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.
|
||||
*
|
||||
* GnuPG 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
|
||||
*/
|
||||
|
||||
#ifdef PLUTO
|
||||
#include <gmp.h>
|
||||
#include <freeswan.h>
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "gcryptfix.h"
|
||||
#else
|
||||
/* #include <config.h> */
|
||||
/* #include <stdio.h> */
|
||||
/* #include <stdlib.h> */
|
||||
/* #include "util.h" */
|
||||
/* #include "types.h" */
|
||||
#endif
|
||||
|
||||
/* Note: 2 is not included because it can be tested more easily
|
||||
* by looking at bit 0. The last entry in this list is marked by a zero
|
||||
*/
|
||||
ushort
|
||||
small_prime_numbers[] = {
|
||||
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
|
||||
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
|
||||
103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
|
||||
157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
|
||||
211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
|
||||
269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
|
||||
331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
|
||||
389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
|
||||
449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
|
||||
509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
|
||||
587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
|
||||
643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
|
||||
709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
|
||||
773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
|
||||
853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
|
||||
919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
|
||||
991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
|
||||
1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
|
||||
1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
|
||||
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
|
||||
1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
|
||||
1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
|
||||
1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
|
||||
1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
|
||||
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
|
||||
1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
|
||||
1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
|
||||
1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
|
||||
1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
|
||||
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
|
||||
1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
|
||||
1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
|
||||
1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
|
||||
1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
|
||||
2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
|
||||
2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
|
||||
2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
|
||||
2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
|
||||
2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
|
||||
2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
|
||||
2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
|
||||
2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
|
||||
2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
|
||||
2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
|
||||
2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
|
||||
2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
|
||||
2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
|
||||
2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
|
||||
2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
|
||||
3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
|
||||
3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
|
||||
3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
|
||||
3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
|
||||
3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
|
||||
3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
|
||||
3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
|
||||
3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
|
||||
3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
|
||||
3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
|
||||
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
|
||||
3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
|
||||
3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
|
||||
3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
|
||||
3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
|
||||
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
|
||||
4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
|
||||
4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
|
||||
4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
|
||||
4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
|
||||
4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
|
||||
4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
|
||||
4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
|
||||
4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
|
||||
4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
|
||||
4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
|
||||
4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
|
||||
4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
|
||||
4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
|
||||
4957, 4967, 4969, 4973, 4987, 4993, 4999,
|
||||
0
|
||||
};
|
||||
|
||||
|
|
@ -26,6 +26,9 @@
|
|||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "connections.h"
|
||||
|
@ -34,7 +37,6 @@
|
|||
#include "log.h"
|
||||
#include "packet.h" /* so we can calculate sizeof(struct isakmp_hdr) */
|
||||
#include "keys.h" /* for free_public_key */
|
||||
#include "rnd.h"
|
||||
#include "timer.h"
|
||||
#include "whack.h"
|
||||
#include "demux.h" /* needs packet.h */
|
||||
|
@ -81,8 +83,7 @@ struct msgid_list
|
|||
struct msgid_list *next;
|
||||
};
|
||||
|
||||
bool
|
||||
reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
|
||||
bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
|
||||
{
|
||||
struct msgid_list *p;
|
||||
|
||||
|
@ -100,20 +101,22 @@ reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
msgid_t
|
||||
generate_msgid(struct state *isakmp_sa)
|
||||
msgid_t generate_msgid(struct state *isakmp_sa)
|
||||
{
|
||||
int timeout = 100; /* only try so hard for unique msgid */
|
||||
msgid_t msgid;
|
||||
rng_t *rng;
|
||||
|
||||
passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
get_rnd_bytes((void *) &msgid, sizeof(msgid));
|
||||
rng->get_bytes(rng, sizeof(msgid), (void *) &msgid);
|
||||
if (msgid != 0 && reserve_msgid(isakmp_sa, msgid))
|
||||
{
|
||||
break;
|
||||
|
||||
}
|
||||
if (--timeout == 0)
|
||||
{
|
||||
plog("gave up looking for unique msgid; using 0x%08lx"
|
||||
|
@ -121,6 +124,7 @@ generate_msgid(struct state *isakmp_sa)
|
|||
break;
|
||||
}
|
||||
}
|
||||
rng->destroy(rng);
|
||||
return msgid;
|
||||
}
|
||||
|
||||
|
@ -131,8 +135,8 @@ generate_msgid(struct state *isakmp_sa)
|
|||
|
||||
static struct state *statetable[STATE_TABLE_SIZE];
|
||||
|
||||
static struct state **
|
||||
state_hash(const u_char *icookie, const u_char *rcookie, const ip_address *peer)
|
||||
static struct state **state_hash(const u_char *icookie, const u_char *rcookie,
|
||||
const ip_address *peer)
|
||||
{
|
||||
u_int i = 0, j;
|
||||
const unsigned char *byte_ptr;
|
||||
|
@ -162,8 +166,7 @@ state_hash(const u_char *icookie, const u_char *rcookie, const ip_address *peer)
|
|||
* Caller must schedule an event for this object so that it doesn't leak.
|
||||
* Caller must insert_state().
|
||||
*/
|
||||
struct state *
|
||||
new_state(void)
|
||||
struct state *new_state(void)
|
||||
{
|
||||
static const struct state blank_state; /* initialized all to zero & NULL */
|
||||
static so_serial_t next_so = SOS_FIRST;
|
||||
|
@ -181,8 +184,7 @@ new_state(void)
|
|||
/*
|
||||
* Initialize the state table (and mask*).
|
||||
*/
|
||||
void
|
||||
init_states(void)
|
||||
void init_states(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -197,8 +199,7 @@ init_states(void)
|
|||
* If this turns out to be a significant CPU hog, it could be
|
||||
* improved to use a hash table rather than sequential seartch.
|
||||
*/
|
||||
struct state *
|
||||
state_with_serialno(so_serial_t sn)
|
||||
struct state *state_with_serialno(so_serial_t sn)
|
||||
{
|
||||
if (sn >= SOS_FIRST)
|
||||
{
|
||||
|
@ -217,8 +218,7 @@ state_with_serialno(so_serial_t sn)
|
|||
* at the begining of list.
|
||||
* Needs cookies, connection, and msgid.
|
||||
*/
|
||||
void
|
||||
insert_state(struct state *st)
|
||||
void insert_state(struct state *st)
|
||||
{
|
||||
struct state **p = state_hash(st->st_icookie, st->st_rcookie
|
||||
, &st->st_connection->spd.that.host_addr);
|
||||
|
@ -244,8 +244,7 @@ insert_state(struct state *st)
|
|||
|
||||
/* unlink a state object from the hash table, but don't free it
|
||||
*/
|
||||
void
|
||||
unhash_state(struct state *st)
|
||||
void unhash_state(struct state *st)
|
||||
{
|
||||
/* unlink from forward chain */
|
||||
struct state **p = st->st_hashchain_prev == NULL
|
||||
|
@ -270,15 +269,15 @@ unhash_state(struct state *st)
|
|||
/* Free the Whack socket file descriptor.
|
||||
* This has the side effect of telling Whack that we're done.
|
||||
*/
|
||||
void
|
||||
release_whack(struct state *st)
|
||||
void release_whack(struct state *st)
|
||||
{
|
||||
close_any(st->st_whack_sock);
|
||||
}
|
||||
|
||||
/* delete a state object */
|
||||
void
|
||||
delete_state(struct state *st)
|
||||
/**
|
||||
* Delete a state object
|
||||
*/
|
||||
void delete_state(struct state *st)
|
||||
{
|
||||
struct connection *const c = st->st_connection;
|
||||
struct state *old_cur_state = cur_state == st? NULL : cur_state;
|
||||
|
@ -372,11 +371,10 @@ delete_state(struct state *st)
|
|||
free(st);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Is a connection in use by some state?
|
||||
*/
|
||||
bool
|
||||
states_use_connection(struct connection *c)
|
||||
bool states_use_connection(struct connection *c)
|
||||
{
|
||||
/* are there any states still using it? */
|
||||
struct state *st = NULL;
|
||||
|
@ -390,13 +388,12 @@ states_use_connection(struct connection *c)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* delete all states that were created for a given connection.
|
||||
/**
|
||||
* Delete all states that were created for a given connection.
|
||||
* if relations == TRUE, then also delete states that share
|
||||
* the same phase 1 SA.
|
||||
*/
|
||||
void
|
||||
delete_states_by_connection(struct connection *c, bool relations)
|
||||
void delete_states_by_connection(struct connection *c, bool relations)
|
||||
{
|
||||
int pass;
|
||||
/* this kludge avoids an n^2 algorithm */
|
||||
|
@ -465,11 +462,11 @@ delete_states_by_connection(struct connection *c, bool relations)
|
|||
c->kind = ck;
|
||||
}
|
||||
|
||||
/* Walk through the state table, and delete each state whose phase 1 (IKE)
|
||||
/**
|
||||
* Walk through the state table, and delete each state whose phase 1 (IKE)
|
||||
* peer is among those given.
|
||||
*/
|
||||
void
|
||||
delete_states_by_peer(ip_address *peer)
|
||||
void delete_states_by_peer(ip_address *peer)
|
||||
{
|
||||
char peerstr[ADDRTOT_BUF];
|
||||
int i;
|
||||
|
@ -512,8 +509,7 @@ delete_states_by_peer(ip_address *peer)
|
|||
* Caller must schedule an event for this object so that it doesn't leak.
|
||||
* Caller must insert_state().
|
||||
*/
|
||||
struct state *
|
||||
duplicate_state(struct state *st)
|
||||
struct state *duplicate_state(struct state *st)
|
||||
{
|
||||
struct state *nst;
|
||||
|
||||
|
@ -558,14 +554,11 @@ void for_each_state(void *(f)(struct state *, void *data), void *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
/**
|
||||
* Find a state object.
|
||||
*/
|
||||
struct state *
|
||||
find_state(const u_char *icookie
|
||||
, const u_char *rcookie
|
||||
, const ip_address *peer
|
||||
, msgid_t /*network order*/ msgid)
|
||||
struct state *find_state(const u_char *icookie, const u_char *rcookie,
|
||||
const ip_address *peer, msgid_t msgid)
|
||||
{
|
||||
struct state *st = *state_hash(icookie, rcookie, peer);
|
||||
|
||||
|
@ -594,11 +587,11 @@ find_state(const u_char *icookie
|
|||
return st;
|
||||
}
|
||||
|
||||
/* Find the state that sent a packet
|
||||
/**
|
||||
* Find the state that sent a packet
|
||||
* ??? this could be expensive -- it should be rate-limited to avoid DoS
|
||||
*/
|
||||
struct state *
|
||||
find_sender(size_t packet_len, u_char *packet)
|
||||
struct state *find_sender(size_t packet_len, u_char *packet)
|
||||
{
|
||||
int i;
|
||||
struct state *st;
|
||||
|
@ -621,11 +614,9 @@ find_sender(size_t packet_len, u_char *packet)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct state *
|
||||
find_phase2_state_to_delete(const struct state *p1st
|
||||
, u_int8_t protoid
|
||||
, ipsec_spi_t spi
|
||||
, bool *bogus)
|
||||
struct state *find_phase2_state_to_delete(const struct state *p1st,
|
||||
u_int8_t protoid, ipsec_spi_t spi,
|
||||
bool *bogus)
|
||||
{
|
||||
struct state *st;
|
||||
int i;
|
||||
|
@ -655,10 +646,10 @@ find_phase2_state_to_delete(const struct state *p1st
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Find newest Phase 1 negotiation state object for suitable for connection c
|
||||
/**
|
||||
* Find newest Phase 1 negotiation state object for suitable for connection c
|
||||
*/
|
||||
struct state *
|
||||
find_phase1_state(const struct connection *c, lset_t ok_states)
|
||||
struct state *find_phase1_state(const struct connection *c, lset_t ok_states)
|
||||
{
|
||||
struct state
|
||||
*st,
|
||||
|
@ -676,9 +667,8 @@ find_phase1_state(const struct connection *c, lset_t ok_states)
|
|||
return best;
|
||||
}
|
||||
|
||||
void
|
||||
state_eroute_usage(ip_subnet *ours, ip_subnet *his
|
||||
, unsigned long count, time_t nw)
|
||||
void state_eroute_usage(ip_subnet *ours, ip_subnet *his, unsigned long count,
|
||||
time_t nw)
|
||||
{
|
||||
struct state *st;
|
||||
int i;
|
||||
|
@ -717,9 +707,8 @@ state_eroute_usage(ip_subnet *ours, ip_subnet *his
|
|||
});
|
||||
}
|
||||
|
||||
void fmt_state(bool all, struct state *st, time_t n
|
||||
, char *state_buf, size_t state_buf_len
|
||||
, char *state_buf2, size_t state_buf2_len)
|
||||
void fmt_state(bool all, struct state *st, time_t n, char *state_buf,
|
||||
size_t state_buf_len, char *state_buf2, size_t state_buf2_len)
|
||||
{
|
||||
/* what the heck is interesting about a state? */
|
||||
const struct connection *c = st->st_connection;
|
||||
|
@ -835,8 +824,7 @@ void fmt_state(bool all, struct state *st, time_t n
|
|||
* isakmp_sa (XXX probably wrong)
|
||||
*
|
||||
*/
|
||||
static int
|
||||
state_compare(const void *a, const void *b)
|
||||
static int state_compare(const void *a, const void *b)
|
||||
{
|
||||
const struct state *sap = *(const struct state *const *)a;
|
||||
struct connection *ca = sap->st_connection;
|
||||
|
@ -848,8 +836,7 @@ state_compare(const void *a, const void *b)
|
|||
return connection_compare(ca, cb);
|
||||
}
|
||||
|
||||
void
|
||||
show_states_status(bool all, const char *name)
|
||||
void show_states_status(bool all, const char *name)
|
||||
{
|
||||
time_t n = now();
|
||||
int i;
|
||||
|
@ -919,8 +906,7 @@ show_states_status(bool all, const char *name)
|
|||
* If we can't find one easily, choose 0 (a bad SPI,
|
||||
* no matter what order) indicating failure.
|
||||
*/
|
||||
void
|
||||
find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
|
||||
void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
|
||||
{
|
||||
int tries = 0;
|
||||
cpi_t base = *latest_cpi;
|
||||
|
@ -972,16 +958,16 @@ startover:
|
|||
* If we can't find one easily, return 0 (a bad SPI,
|
||||
* no matter what order) indicating failure.
|
||||
*/
|
||||
ipsec_spi_t
|
||||
uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
|
||||
ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
|
||||
{
|
||||
int tries = 0;
|
||||
int i;
|
||||
rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
|
||||
startover:
|
||||
|
||||
/* network order makes first two bytes our target */
|
||||
get_rnd_bytes((u_char *)&cpi, 2);
|
||||
rng->get_bytes(rng, 2, (u_char *)&cpi);
|
||||
|
||||
/* Make sure that the result is unique.
|
||||
* Hard work. If there is no unique value, we'll loop forever!
|
||||
|
@ -998,11 +984,15 @@ startover:
|
|||
&& cpi == s->st_ipcomp.attrs.spi)
|
||||
{
|
||||
if (++tries == 20)
|
||||
{
|
||||
rng->destroy(rng);
|
||||
return 0; /* FAILURE */
|
||||
}
|
||||
goto startover;
|
||||
}
|
||||
}
|
||||
}
|
||||
rng->destroy(rng);
|
||||
return cpi;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "defs.h"
|
||||
#include "connections.h"
|
||||
|
@ -33,14 +36,14 @@
|
|||
#include "kernel.h"
|
||||
#include "server.h"
|
||||
#include "log.h"
|
||||
#include "rnd.h"
|
||||
#include "timer.h"
|
||||
#include "whack.h"
|
||||
#include "nat_traversal.h"
|
||||
|
||||
/* monotonic version of time(3) */
|
||||
time_t
|
||||
now(void)
|
||||
/**
|
||||
* monotonic version of time(3)
|
||||
*/
|
||||
time_t now(void)
|
||||
{
|
||||
static time_t delta = 0
|
||||
, last_time = 0;
|
||||
|
@ -64,11 +67,10 @@ now(void)
|
|||
|
||||
static struct event *evlist = (struct event *) NULL;
|
||||
|
||||
/*
|
||||
/**
|
||||
* This routine places an event in the event list.
|
||||
*/
|
||||
void
|
||||
event_schedule(enum event_type type, time_t tm, struct state *st)
|
||||
void event_schedule(enum event_type type, time_t tm, struct state *st)
|
||||
{
|
||||
struct event *ev = malloc_thing(struct event);
|
||||
|
||||
|
@ -133,11 +135,24 @@ event_schedule(enum event_type type, time_t tm, struct state *st)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Generate the secret value for responder cookies, and
|
||||
* schedule an event for refresh.
|
||||
*/
|
||||
void init_secret(void)
|
||||
{
|
||||
rng_t *rng;
|
||||
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
|
||||
rng->get_bytes(rng, sizeof(secret_of_the_day), secret_of_the_day);
|
||||
rng->destroy(rng);
|
||||
event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the first event on the list.
|
||||
*/
|
||||
void
|
||||
handle_timer_event(void)
|
||||
void handle_timer_event(void)
|
||||
{
|
||||
time_t tm;
|
||||
struct event *ev = evlist;
|
||||
|
@ -434,12 +449,11 @@ handle_timer_event(void)
|
|||
reset_cur_state();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Return the time until the next event in the queue
|
||||
* expires (never negative), or -1 if no jobs in queue.
|
||||
*/
|
||||
long
|
||||
next_event(void)
|
||||
long next_event(void)
|
||||
{
|
||||
time_t tm;
|
||||
|
||||
|
@ -465,11 +479,10 @@ next_event(void)
|
|||
return evlist->ev_time - tm;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Delete an event.
|
||||
*/
|
||||
void
|
||||
delete_event(struct state *st)
|
||||
void delete_event(struct state *st)
|
||||
{
|
||||
if (st->st_event != (struct event *) NULL)
|
||||
{
|
||||
|
@ -500,11 +513,10 @@ delete_event(struct state *st)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Delete a DPD event.
|
||||
*/
|
||||
void
|
||||
delete_dpd_event(struct state *st)
|
||||
void delete_dpd_event(struct state *st)
|
||||
{
|
||||
if (st->st_dpd_event != (struct event *) NULL)
|
||||
{
|
||||
|
@ -529,11 +541,10 @@ delete_dpd_event(struct state *st)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Free remaining events
|
||||
*/
|
||||
void
|
||||
free_events(void)
|
||||
void free_events(void)
|
||||
{
|
||||
struct event *ev_tmp, *ev;
|
||||
|
||||
|
|
|
@ -31,3 +31,4 @@ extern void delete_event(struct state *st);
|
|||
extern void delete_dpd_event(struct state *st);
|
||||
extern void daily_log_event(void);
|
||||
extern void free_events(void);
|
||||
extern void init_secret(void);
|
||||
|
|
|
@ -90,7 +90,7 @@ struct vid_struct {
|
|||
unsigned short flags;
|
||||
const char *data;
|
||||
const char *descr;
|
||||
const char *vid;
|
||||
char *vid;
|
||||
u_int vid_len;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ AM_CFLAGS = \
|
|||
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
|
||||
-DPLUGINS=\""${pluto_plugins}\"" \
|
||||
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
|
||||
-DNO_CREDENTIAL_FACTORY \
|
||||
-DDEBUG -DNO_PLUTO
|
||||
|
||||
LIBSTRONGSWANBUILDDIR=$(top_builddir)/src/libstrongswan
|
||||
|
@ -28,7 +29,7 @@ LIBCRYPTOBUILDDIR=$(top_builddir)/src/libcrypto
|
|||
|
||||
scepclient_LDADD = \
|
||||
ca.o crl.o certs.o constants.o defs.o fetch.o id.o keys.o lex.o \
|
||||
md2.o md5.o mp_defs.o ocsp.o pem.o pgp.o pkcs1.o pkcs7.o rnd.o sha1.o \
|
||||
md2.o md5.o mp_defs.o ocsp.o pem.o pgp.o pkcs1.o pkcs7.o sha1.o \
|
||||
smartcard.o x509.o \
|
||||
$(LIBSTRONGSWANBUILDDIR)/libstrongswan.la \
|
||||
$(LIBFREESWANBUILDDIR)/libfreeswan.a \
|
||||
|
@ -94,9 +95,6 @@ pkcs1.o : $(PLUTODIR)/pkcs1.c $(PLUTODIR)/pkcs1.h
|
|||
pkcs7.o : $(PLUTODIR)/pkcs7.c $(PLUTODIR)/pkcs7.h
|
||||
$(COMPILE) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
rnd.o : $(PLUTODIR)/rnd.c $(PLUTODIR)/rnd.h
|
||||
$(COMPILE) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
sha1.o : $(PLUTODIR)/sha1.c $(PLUTODIR)/sha1.h
|
||||
$(COMPILE) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/mp_defs.h"
|
||||
|
@ -58,45 +61,6 @@
|
|||
* @return TRUE, if succeeded, FALSE otherwise
|
||||
*/
|
||||
|
||||
static bool
|
||||
get_true_random_bytes(size_t nbytes, char *buf)
|
||||
{
|
||||
size_t ndone;
|
||||
size_t got;
|
||||
char *device = DEV_RANDOM;
|
||||
|
||||
int dev = open(DEV_RANDOM, 0);
|
||||
|
||||
if (dev < 0)
|
||||
{
|
||||
fprintf(stderr, "could not open random device %s", device);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("getting %d bytes from %s...", (int) nbytes, device)
|
||||
)
|
||||
|
||||
ndone = 0;
|
||||
while (ndone < nbytes)
|
||||
{
|
||||
got = read(dev, buf + ndone, nbytes - ndone);
|
||||
if (got < 0)
|
||||
{
|
||||
fprintf(stderr, "read error on %s", device);
|
||||
return FALSE;
|
||||
}
|
||||
if (got == 0)
|
||||
{
|
||||
fprintf(stderr, "eof on %s", device);
|
||||
return FALSE;
|
||||
}
|
||||
ndone += got;
|
||||
}
|
||||
close(dev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initialize an mpz_t to a random number, specified bit count
|
||||
*
|
||||
|
@ -110,17 +74,20 @@ get_true_random_bytes(size_t nbytes, char *buf)
|
|||
* @param[in] nbits length of var in bits (known to be a multiple of BITS_PER_BYTE)
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
*/
|
||||
static bool
|
||||
init_random(mpz_t var, int nbits)
|
||||
static bool init_random(mpz_t var, int nbits)
|
||||
{
|
||||
size_t nbytes = (size_t)(nbits/BITS_PER_BYTE);
|
||||
char random_buf[RSA_MAX_OCTETS/2];
|
||||
rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
|
||||
|
||||
assert(nbytes <= sizeof(random_buf));
|
||||
|
||||
if (!get_true_random_bytes(nbytes, random_buf))
|
||||
if (!rng)
|
||||
{
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
assert(nbytes <= sizeof(random_buf));
|
||||
rng->get_bytes(rng, nbytes, random_buf);
|
||||
rng->destroy(rng);
|
||||
|
||||
random_buf[0] |= 01 << (BITS_PER_BYTE-1); /* force high bit on */
|
||||
random_buf[nbytes-1] |= 01; /* force low bit on */
|
||||
n_to_mpz(var, random_buf, nbytes);
|
||||
|
@ -138,8 +105,7 @@ init_random(mpz_t var, int nbits)
|
|||
* @param[in] eval E-Value, 0 means don't bother w. tweak
|
||||
* @return 1 on success, 0 otherwise
|
||||
*/
|
||||
static bool
|
||||
init_prime(mpz_t var, int nbits, int eval)
|
||||
static bool init_prime(mpz_t var, int nbits, int eval)
|
||||
{
|
||||
unsigned long tries;
|
||||
size_t len;
|
||||
|
@ -194,8 +160,7 @@ init_prime(mpz_t var, int nbits, int eval)
|
|||
* @param[in] nbits size of rsa key in bits
|
||||
* @return RSA_public_key_t containing the generated RSA key
|
||||
*/
|
||||
err_t
|
||||
generate_rsa_private_key(int nbits, RSA_private_key_t *key)
|
||||
err_t generate_rsa_private_key(int nbits, RSA_private_key_t *key)
|
||||
{
|
||||
mpz_t p, q, n, e, d, exp1, exp2, coeff;
|
||||
mpz_t m, q1, t; /* temporary variables*/
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
#include <asn1/asn1.h>
|
||||
#include <asn1/asn1_parser.h>
|
||||
#include <asn1/oid.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/rnd.h"
|
||||
#include "../pluto/pkcs1.h"
|
||||
#include "../pluto/fetch.h"
|
||||
#include "../pluto/log.h"
|
||||
|
@ -355,8 +355,11 @@ chunk_t scep_senderNonce_attribute(void)
|
|||
const size_t nonce_len = 16;
|
||||
u_char nonce_buf[nonce_len];
|
||||
chunk_t senderNonce = { nonce_buf, nonce_len };
|
||||
rng_t *rng;
|
||||
|
||||
get_rnd_bytes(nonce_buf, nonce_len);
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
rng->get_bytes(rng, nonce_len, nonce_buf);
|
||||
rng->destroy(rng);
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
||||
, ASN1_senderNonce_oid
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <gmp.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
#include <asn1/asn1.h>
|
||||
|
@ -48,7 +49,6 @@
|
|||
#include "../pluto/pkcs1.h"
|
||||
#include "../pluto/pkcs7.h"
|
||||
#include "../pluto/certs.h"
|
||||
#include "../pluto/rnd.h"
|
||||
|
||||
#include "rsakey.h"
|
||||
#include "pkcs10.h"
|
||||
|
@ -747,9 +747,6 @@ int main(int argc, char **argv)
|
|||
lib->settings->get_str(lib->settings, "scepclient.load", PLUGINS));
|
||||
print_plugins();
|
||||
|
||||
init_rnd_pool();
|
||||
init_fetch();
|
||||
|
||||
if ((filetype_out == 0) && (!request_ca_certificate))
|
||||
{
|
||||
usage ("--out filetype required");
|
||||
|
|
Loading…
Reference in New Issue