[vpn-help] Unable to verify remote peer certificate

Tai-hwa Liang avatar at mmlab.cse.yzu.edu.tw
Thu Apr 15 21:11:08 CDT 2010


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.
-------------- next part --------------
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 );



More information about the vpn-help mailing list