On Wed, 31 Mar 2010, Michael wrote:
[...]
 ii : unable to get local issuer certificate(20) at depth:0
 ii : subject :/CN=name.host.tld
 !! : unable to verify remote peer certificate

The host 'name.host.tld' is in the SubjectAltName of the X.509
certificate loaded on the ike v1 server m0n0wall 1.31. I have
concatanated the root and intermediate CA certificates of CaCert.org
to the file 'cacert-combi.pem':

s:ident-server-type:asn1dn
s:auth-server-cert:/home/username/.ike/certs/cacert-combi.pem
s:auth-client-cert:/home/username/.ike/certs/myclienthost-cacert-rsa-4096-crt.pem
s:auth-client-key:/home/username/.ike/keys/myclienthost-cacert-rsa-4096-key.pem

What can be the problem?

The default verification facility in UN*X version of Shrew VPN doesn't support multiple levels of CAs. I've submitted a patch a few years ago
which should be able to workaround this problem.

Since the attached patch was for 2.1.0 release, you're likely to have to resolve possible conflict after applying it to recent release.
diff -rup ike.orig/source/iked/iked.h ike/source/iked/iked.h
--- ike.orig/source/iked/iked.h 2008-06-10 10:13:52.000000000 +0800
+++ ike/source/iked/iked.h      2008-08-06 17:59:08.000000000 +0800
@@ -547,12 +551,17 @@ typedef class _IKED

        // x.509 certificate helper functions

 

        bool    cert_2_bdata( BDATA & cert, X509 * x509 );

+       bool    certs_2_bdata( BDATA & certs, STACK_OF(X509) * x509_chain );

        bool    bdata_2_cert( X509 ** x509, BDATA & cert );

+       bool    bdata_2_certs( STACK_OF(X509) ** x509_chain, BDATA & cert );

 

        long    cert_save( BDATA & cert, char * fpath );

        long    cert_load( BDATA & cert, char * fpath, bool ca, BDATA & pass );

        bool    cert_load_pem( BDATA & cert, FILE * fp, bool ca, BDATA & pass );

        bool    cert_load_p12( BDATA & cert, FILE * fp, bool ca, BDATA & pass );

+       long    certs_load( BDATA & certs, char * fpath, bool ca, BDATA & pass 
);

+       bool    certs_load_pem( BDATA & certs, FILE * fp, bool ca, BDATA & pass 
);

+       bool    certs_load_p12( BDATA & certs, FILE * fp, bool ca, BDATA & pass 
);

        bool    cert_desc( BDATA & cert, BDATA & text );

        bool    cert_subj( BDATA & cert, BDATA & subj );

        bool    asn1_text( BDATA & asn1, BDATA & text );

diff -rup ike.orig/source/iked/ike.io.admin.cpp ike/source/iked/ike.io.admin.cpp
--- ike.orig/source/iked/ike.io.admin.cpp       2008-05-19 05:35:53.000000000 
+0800
+++ ike/source/iked/ike.io.admin.cpp    2008-08-06 18:20:58.000000000 +0800
@@ -406,7 +406,7 @@ long _IKED::loop_ipc_client( IKEI * ikei
 

                                                        log.txt( LLOG_INFO, "<A 
: remote cert \'%s\' message\n", text.text() );

 

-                                                       long loaded = 
cert_load( tunnel->peer->cert_r, text.text(), true, tunnel->peer->fpass );

+                                                       long loaded = 
certs_load( tunnel->peer->cert_r, text.text(), true, tunnel->peer->fpass );

 

                                                        switch( loaded )

                                                        {

diff -rup ike.orig/source/iked/ike.keyfile.cpp ike/source/iked/ike.keyfile.cpp
--- ike.orig/source/iked/ike.keyfile.cpp        2008-02-20 15:10:05.000000000 
+0800
+++ ike/source/iked/ike.keyfile.cpp     2008-08-06 18:44:32.000000000 +0800
@@ -79,6 +79,21 @@ bool _IKED::cert_2_bdata( BDATA & cert, 
        return true;

 }

 

+bool _IKED::certs_2_bdata( BDATA & certs, STACK_OF(X509) * x509_chain )

+{

+       int size = i2d_ASN1_SET_OF_X509(x509_chain, NULL, i2d_X509,

+           V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);

+

+       certs.size( size );

+

+       unsigned char * cert_buff = certs.buff();

+       if( i2d_ASN1_SET_OF_X509(x509_chain, &cert_buff, i2d_X509,

+           V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE) < size )

+               return false;

+

+       return true;

+}

+

 bool _IKED::bdata_2_cert( X509 ** x509, BDATA & cert )

 {

        X509CONST unsigned char * cert_buff = cert.buff();

@@ -90,6 +105,123 @@ bool _IKED::bdata_2_cert( X509 ** x509, 
        return true;

 }

 

+bool _IKED::bdata_2_certs( STACK_OF(X509) ** x509_chain, BDATA & certs )

+{

+       X509CONST unsigned char * cert_buff = certs.buff();

+

+       *x509_chain = d2i_ASN1_SET_OF_X509( NULL, &cert_buff,

+           ( long ) certs.size(), d2i_X509, X509_free,

+           V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);

+

+       if( *x509_chain == NULL )

+               return false;

+

+       return true;

+}

+

+long _IKED::certs_load( BDATA & certs, char * fpath, bool ca, BDATA & pass )

+{

+#ifdef WIN32

+

+       FILE * fp;

+       if( fopen_s( &fp, fpath, "rb" ) )

+               return FILE_PATH;

+

+#else

+

+       FILE * fp = fopen( fpath, "rb" );

+       if( !fp )

+               return FILE_PATH;

+

+#endif

+

+       bool loaded = certs_load_pem( certs, fp, ca, pass );

+       if( !loaded )

+               loaded = certs_load_p12( certs, fp, ca, pass );

+

+       fclose( fp );

+

+       if( !loaded )

+               return FILE_FAIL;

+

+       return FILE_OK;

+}

+

+bool _IKED::certs_load_pem( BDATA & certs, FILE * fp, bool ca, BDATA & pass )

+{

+       fseek( fp, 0, SEEK_SET );

+

+       STACK_OF(X509) *cert_chain = sk_X509_new_null();

+       STACK_OF(X509_INFO) *allcerts = NULL;

+

+       allcerts = PEM_X509_INFO_read(fp, NULL, keyfile_cb, &pass);

+       if (allcerts == NULL || sk_X509_INFO_num(allcerts) == 0)

+       {

+               sk_X509_free(cert_chain);

+               return (false);

+       }

+       for (int i = 0; i < sk_X509_INFO_num(allcerts); i++)

+       {

+               X509_INFO *xi = sk_X509_INFO_value (allcerts, i);

+               if (xi->x509)

+               {

+                       sk_X509_push(cert_chain, xi->x509);

+                       xi->x509 = NULL;

+               }

+       }

+

+       certs_2_bdata( certs, cert_chain );

+

+       sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
+

+       return (true);

+}

+

+bool _IKED::certs_load_p12( BDATA & certs, FILE * fp, bool ca, BDATA & pass )

+{

+       fseek( fp, 0, SEEK_SET );

+

+       PKCS12 * p12 = d2i_PKCS12_fp( fp, NULL );

+       if( p12 == NULL )

+               return false;

+

+       X509 * x509 = NULL;

+

+       BDATA passnull;

+       passnull.set( pass );

+       passnull.add( 0, 1 );

+

+       if( ca )

+       {

+               STACK_OF( X509 ) * stack = NULL;

+

+               if( PKCS12_parse( p12, ( const char * ) passnull.buff(), NULL, 
NULL, &stack ) )

+               {

+                       if ( stack == NULL )

+                       {

+                               PKCS12_free( p12 );

+                               return false;

+                       }

+                       certs_2_bdata( certs, stack );

+                       sk_X509_free( stack );

+                       PKCS12_free( p12 );

+                       return true;

+               }

+       }

+       else

+               PKCS12_parse( p12, ( const char * ) passnull.buff(), NULL, 
&x509, NULL );

+

+       PKCS12_free( p12 );

+

+       if( x509 == NULL )

+               return false;

+

+       cert_2_bdata( certs, x509 );

+       X509_free( x509 );

+

+       return true;

+}

+

 long _IKED::cert_load( BDATA & cert, char * fpath, bool ca, BDATA & pass )

 {

 #ifdef WIN32

@@ -566,14 +698,17 @@ bool _IKED::cert_verify( IDB_LIST_CERT &
        // load ca and add to store

        //

 

-       X509 * x509_ca;

-       if( !bdata_2_cert( &x509_ca, ca ) )

+       STACK_OF(X509) * x509_ca;

+       if( !bdata_2_certs( &x509_ca, ca ) )

        {

                X509_STORE_free( store );

                return false;

        }

 

-       X509_STORE_add_cert( store, x509_ca );

+       for (int i = 0; i < sk_X509_num(x509_ca); i++)

+       {

+               X509_STORE_add_cert( store, sk_X509_value(x509_ca, i) );

+       }

 

 #ifdef WIN32

 

@@ -678,7 +837,7 @@ bool _IKED::cert_verify( IDB_LIST_CERT &
        // cleanup

        //

 

-       X509_free( x509_ca );

+       sk_X509_free( x509_ca );

        X509_STORE_free( store );

 

        return ( result > 0 );

_______________________________________________
vpn-help mailing list
[email protected]
http://lists.shrew.net/mailman/listinfo/vpn-help

Reply via email to