[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