public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* RE: [ECOS] RE: RE: On Porting OpenSSL v1.0.0c
@ 2011-04-27 19:48 amassa
  0 siblings, 0 replies; 3+ messages in thread
From: amassa @ 2011-04-27 19:48 UTC (permalink / raw)
  To: Retallack, Mark; +Cc: 'ecos-discuss@ecos.sourceware.org'

Hi,

Thanks for the reply.

I do have a call to get the further errors and code similar to the one you included below.  It seems errno is 0 (showing no error), but I need to look into this further to see if it is implemented correctly on this platform because SSL_get_error returns 5 (as you mentioned).

I have also tried to use the callback during connection to obtain more information.  These are the output messages (snippet) I am seeing after the attempt to perform SSL_connect():

do the SSL connection
SSL_connect:before/connect initialization
SSL_connect:error in SSLv3 write client hello A
SSL_connect status  -1
SSL_connect Error  5
sockerrno to connect, err = 0 (No error)
SSL Verify OK
SSL_connect Failed

The callback status returns "error in SSLv3 write client hello A".

I have implemented my own ioctl() (returning ENOSYS) to handle any calls into that function.

Any further ideas are greatly appreciated.

Thanks,
Anthony

---- "Retallack wrote: 
> Hi, 
> 
> One thing hat comes to mind, error 5 is SSL_ERROR_SYSCALL, see: http://www.openssl.org/docs/ssl/SSL_get_error.html
> 
> It also suggests some more debug to use to find out what has happened (for example errno). You can also use something like the following to get a string of the error:
> 
> unsigned long l;
> while ((l=ERR_get_error()))
> {
>     printf("ssl error: %s\n", ERR_error_string(l,NULL));
> }
> 
> Because the underlying transport is not TCP, it might be returning an error because of blocking/non-blocking differences. Also I believe that openssl can use ioctl calls, this may be failing on a serial file descriptor. 
> 
> Mark Retallack 
> 
> -----Original Message-----
> From: ecos-discuss-owner@ecos.sourceware.org [mailto:ecos-discuss-owner@ecos.sourceware.org] On Behalf Of Anthony Massa
> Sent: 26 April 2011 17:53
> To: ecos-discuss@ecos.sourceware.org
> Subject: [ECOS] RE: RE: On Porting OpenSSL v1.0.0c
> 
> Hi,
> 
> I have OpenSSL built into my image (along with a slightly older version of eCos).  I am not able to use the standard socket interface layer over Ethernet - basically the platform I'm using needs to communicate via serial for the network traffic.  So, basically the socket interface functions (connect, send, recv) are implemented to use this serial interface.  I have tested the raw socket interface for the connect, send, and recv functions and they appear to be able to echo with a server properly - so I believe the socket interface is running correctly.
> 
> I am running the test code I included above (ssltest.c) and find that the test is failing at line 725 when the SSL_connect function is called.
> 
> The output I see and errors returned are shown here:
> 
> do the SSL connection
> SSL_connect status  -1
> SSL_connect Error  5
> 
> I appreciate any feedback.
> 
> Thanks,
> Anthony
> 


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [ECOS] RE: RE: On Porting OpenSSL v1.0.0c
  2011-04-26 16:53   ` Anthony Massa
@ 2011-04-27  7:07     ` Retallack, Mark
  0 siblings, 0 replies; 3+ messages in thread
From: Retallack, Mark @ 2011-04-27  7:07 UTC (permalink / raw)
  To: 'amassa@san.rr.com'; +Cc: 'ecos-discuss@ecos.sourceware.org'

Hi, 

One thing hat comes to mind, error 5 is SSL_ERROR_SYSCALL, see: http://www.openssl.org/docs/ssl/SSL_get_error.html

It also suggests some more debug to use to find out what has happened (for example errno). You can also use something like the following to get a string of the error:

unsigned long l;
while ((l=ERR_get_error()))
{
    printf("ssl error: %s\n", ERR_error_string(l,NULL));
}

Because the underlying transport is not TCP, it might be returning an error because of blocking/non-blocking differences. Also I believe that openssl can use ioctl calls, this may be failing on a serial file descriptor. 

Mark Retallack 

-----Original Message-----
From: ecos-discuss-owner@ecos.sourceware.org [mailto:ecos-discuss-owner@ecos.sourceware.org] On Behalf Of Anthony Massa
Sent: 26 April 2011 17:53
To: ecos-discuss@ecos.sourceware.org
Subject: [ECOS] RE: RE: On Porting OpenSSL v1.0.0c

Hi,

I have OpenSSL built into my image (along with a slightly older version of eCos).  I am not able to use the standard socket interface layer over Ethernet - basically the platform I'm using needs to communicate via serial for the network traffic.  So, basically the socket interface functions (connect, send, recv) are implemented to use this serial interface.  I have tested the raw socket interface for the connect, send, and recv functions and they appear to be able to echo with a server properly - so I believe the socket interface is running correctly.

I am running the test code I included above (ssltest.c) and find that the test is failing at line 725 when the SSL_connect function is called.

The output I see and errors returned are shown here:

do the SSL connection
SSL_connect status  -1
SSL_connect Error  5

I appreciate any feedback.

Thanks,
Anthony


--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ECOS] RE: RE: On Porting OpenSSL v1.0.0c
       [not found] ` <03AEFB12CF391F45B74EC59D643A74510787B30FF7@DEFTHW99E24MSX.ww902.siemens.net>
@ 2011-04-26 16:53   ` Anthony Massa
  2011-04-27  7:07     ` Retallack, Mark
  0 siblings, 1 reply; 3+ messages in thread
From: Anthony Massa @ 2011-04-26 16:53 UTC (permalink / raw)
  To: ecos-discuss

[-- Attachment #1: Type: text/plain, Size: 874 bytes --]

Hi,

I have OpenSSL built into my image (along with a slightly older version of eCos).  I am not able to use the standard socket interface layer over Ethernet - basically the platform I'm using needs to communicate via serial for the network traffic.  So, basically the socket interface functions (connect, send, recv) are implemented to use this serial interface.  I have tested the raw socket interface for the connect, send, and recv functions and they appear to be able to echo with a server properly - so I believe the socket interface is running correctly.

I am running the test code I included above (ssltest.c) and find that the test is failing at line 725 when the SSL_connect function is called.

The output I see and errors returned are shown here:

do the SSL connection
SSL_connect status  -1
SSL_connect Error  5

I appreciate any feedback.

Thanks,
Anthony


[-- Attachment #2: ssltest.c --]
[-- Type: text/plain, Size: 24983 bytes --]

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>

#include "os.h"

#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
#include <openssl/bio.h>
#include <openssl/err.h>


//asd


#define ALLOW_INVALID_PURPOSE             0x00000001
#define ALLOW_SELF_SIGNED_CERT_IN_CHAIN   0x00000002
#define VERIFY_SHOW_CERTS                 0x80000000

#define SHUT_RD   0		/* == Win32 SD_RECEIVE */
#define SHUT_WR   1		/* == Win32 SD_SEND    */
#define SHUT_RDWR 2		/* == Win32 SD_BOTH    */


unsigned long verify_control_flags = 0;
int dump_cert_names = 0;
int ignore_all_verify_errors = 0;

char * rootcert = 
"-----BEGIN CERTIFICATE-----\n"
"MIIDbDCCAtWgAwIBAgIBKTANBgkqhkiG9w0BAQQFADCBkTELMAkGA1UEBhMCVVMx\n"
"CzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTYW4gRGllZ28xEzARBgNVBAoTClZlcmlt\n"
"YXRyaXgxDTALBgNVBAsTBFZDQVMxGzAZBgNVBAMTElZlcmltYXRyaXggUk9PVCBD\n"
"QTEgMB4GCSqGSIb3DQEJARYRQ0FAVmVyaW1hdHJpeC5jb20wHhcNMDUwMzIzMjA0\n"
"NzEwWhcNMTUwMzIxMjA0NzEwWjCBhzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNB\n"
"MRMwEQYDVQQKEwpWZXJpbWF0cml4MQ0wCwYDVQQLEwRWQ0FTMRQwEgYDVQQDEwtN\n"
"aWtlIEJlYXR0eTExMC8GCSqGSIb3DQEJARYiU1VCQ0EuMTExMTYxMDgyOTg0M0BW\n"
"ZXJpbWF0cml4LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy0us/E8u\n"
"2vH1x6AcwDHllaMz3SdJ1plknmOPn2IgPHoOdg+PR2ciAR4wOzXUyOkasUhn8FyS\n"
"p+lPQiv/vfMxu6zG4NtwRF5NIWqCG06pXUIYR3JH4HSbfhf+9IIHsn2HwPolBBRq\n"
"zDJRkKKVLWSlYLjneqhWkYCFLkTshSyw2vcCAwEAAaOB2zCB2DAdBgNVHQ4EFgQU\n"
"CfPXPsVfPryHZq9o7/soM3JAtZUwgagGA1UdIwSBoDCBnaGBl6SBlDCBkTELMAkG\n"
"A1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTYW4gRGllZ28xEzARBgNV\n"
"BAoTClZlcmltYXRyaXgxDTALBgNVBAsTBFZDQVMxGzAZBgNVBAMTElZlcmltYXRy\n"
"aXggUk9PVCBDQTEgMB4GCSqGSIb3DQEJARYRQ0FAVmVyaW1hdHJpeC5jb22CAQAw\n"
"DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBr9fD+FC5Of2LJb1pw+hUO\n"
"WKFmgulTkVGO5tFo2EddK5k/RywxJ76QmM+ej0Zz9AsvWDJO6HQmpwm8WQbxyG6F\n"
"jq5xKAUJMSmQv3UYY7uwcmcZbtnU6OYfm5zIz1p7F9oJsCWBX3nPQ3SE7DP7xBBK\n"
"KsHR1fLvK1pdTPsSpJsQvw==\n"
"-----END CERTIFICATE-----\n";


int ip_connect( char * host, int port )
{
	struct sockaddr_in sa;
	int s = -1;
	
	/* Set-up the sockaddr_in structure */
	memset((char *)&sa,0,sizeof(sa));
	sa.sin_family=AF_INET;
	sa.sin_port=(unsigned short)port;
    sa.sin_addr.s_addr = inet_addr(host);

SM_printf("connect port = %x\r\n", sa.sin_port);

	/* Create the socket */
	s = socket( AF_INET, SOCK_STREAM, 0 );
	if (s == -1) {
		SM_printf("failed to create the socket\r\n");
		return -1;
	}

	/* Connect */
	if ( connect( s, (struct sockaddr*)&sa, sizeof(sa) ) == -1 ) {
		SM_printf("failed to connect\r\n");
		close(s);
		return -1;
	} 

	return s;

#if 0

   unsigned long addr;
//   struct sockaddr_in them;
   sockaddr them;
   //struct hostent * pHostEnt;
   //char ** pHostAddr = NULL;
   int s = -1;

   /* resolve IP address */
   addr = inet_addr(host);
   if ( -1 == addr )
   {
      SM_printf("Host address must be an IPv4 IP Address\n");
	//SM_printf("Failed to connect, err = %d (%s)\r\n", e, strerror(e));
      return -1;
   }

   /* Set-up the sockaddr_in structure */
   memset((char *)&them,0,sizeof(them));
   them.sin_family=AF_INET;
   //them.sin_port=htons((unsigned short)port);
   them.sin_port=(unsigned short)port;
   them.sin_addr.s_addr = inet_addr(host);
   //memcpy( (void *)&them.sin_addr, (void *)&addr, sizeof(addr) );


   /* create the socket */
   //s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    s = socket(AF_INET, SOCK_STREAM, 0);
   if (-1 == s) 
   {
	SM_printf("Failed to create socket  %d\n",errno);
      return -1;
   }

   
   if (connect(s, &them, sizeof(them)) == -1) {
//   if (connect(s, &them, sizeof(them) ) == -1 ) 
   {
      int e = errno;
      SM_printf("Failed to connect, err = %d (%s)\n", e, strerror(e) );
      close( s );
      return -1;
   }

   SM_printf("Socket (%d) connect OK to %s:%d\n", s, host, port);
   return s;
#endif
}


void print_cert( X509 * cert )
{
    X509_PURPOSE *ptmp;
    int j, id, i, idret;
    char *pname;
    BIO *STDout=NULL;
    
    // Create BIO object for stdout
    STDout=BIO_new_fp(stdout,BIO_NOCLOSE);

    // Print the certificate text
    X509_print_ex( STDout, cert, 0, 0 );

    // Print the Certificate Purposes
    // This code is from openssl/apps/x509.c
    BIO_printf(STDout, "    Certificate purposes:\n");
    for (j = 0; j < X509_PURPOSE_get_count(); j++)
    {
        ptmp = X509_PURPOSE_get0(j);
        id = X509_PURPOSE_get_id(ptmp);
        pname = X509_PURPOSE_get0_name(ptmp);
        for (i = 0; i < 2; i++)
        {
            idret = X509_check_purpose(cert, id, i);
            BIO_printf(STDout, "        %s%s : ", pname, i ? " CA" : ""); 
            if (idret == 1) 
                BIO_printf(STDout, "Yes\n");
            else if (idret == 0) 
                BIO_printf(STDout, "No\n");
            else 
                BIO_printf(STDout, "Yes (WARNING code=%d)\n", idret);
        }
    }

    // Free our BIO object
    BIO_free_all(STDout);
}



X509 * get_issuer( X509_STORE_CTX *ctx )
{
    X509 *issuer, *tmp_issuer = NULL, *err_cert;
    int res;


    // Ensure we have an X509 Store Context
    if ( !ctx )
    {
       SM_printf( "no CTX\n" );
       return NULL;
    }

    err_cert = X509_STORE_CTX_get_current_cert(ctx);
    if ( NULL == err_cert )
    {
        SM_printf("No cert to get issuer of\n");
        return NULL;
    }

    // Obtain the issuer cert
    issuer = ctx->current_issuer;

    // If the issuer has not been set, try to get it from the trusted 
    // certs in the store.  If this works, the cert will have to be freed
    // later.
    if ( !issuer )
    {
        // It is not set yet, try getting it from the store
        res = X509_STORE_CTX_get1_issuer( &tmp_issuer, ctx, err_cert );
        issuer = tmp_issuer;
        if ( issuer )
        {
            //SM_printf( "Got issuer from trusted certs\n" );
        }
    }

    if ( !issuer)
    {
        // If we did not get the issuer from the trusted certs,
        // try getting it from the stack of untrusted certs.
        // If this works we just get a pointer to the stack 
        // entry and must NOT free it.
        int i;
        X509 *potential_issuer;
        for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
        {
            potential_issuer = sk_X509_value(ctx->untrusted, i);
            if (ctx->check_issued(ctx, err_cert, potential_issuer))
                issuer = potential_issuer;
        }
        if ( issuer )
        {
            //SM_printf("Got issuer from untrusted certs\n");
        }
    }

    if ( !issuer )
    {
       SM_printf( "Could not find issuer cert\n");
    }
    //else 
    //{
    //    SM_printf( "Have issuer cert\n" );
    //}

    // This should be freed to avoid memory leaks, 
    // but this is just a test app, so let it leak!
    //if (tmp_issuer) 
    //    X509_free(tmp_issuer);
    return issuer;

}

void log_ssl_verify_errors( int verify_result )
{
    switch( verify_result ) 
    {
        default:
            SM_printf("UNKNOWN SSL Verify error %ld\n", verify_result);
            break;
        case X509_V_OK:
            SM_printf("SSL Verify OK\n");
            break;
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
            SM_printf("SSL Verify UNABLE_TO_GET_ISSUER_CERT\n");
            break;
        case X509_V_ERR_CERT_NOT_YET_VALID:
            SM_printf("SSL Verify CERT_NOT_YET_VALID\n");
            break;
        case X509_V_ERR_CERT_HAS_EXPIRED:
            SM_printf("SSL Verify CERT_HAS_EXPIRED\n");
            break;
        case X509_V_ERR_INVALID_PURPOSE:
            SM_printf("SSL Verify INVALID_PURPOSE\n");
            break;
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
            SM_printf("SSL Verify UNABLE_TO_GET_ISSUER_CERT_LOCALLY\n");
            break;
        case X509_V_ERR_PATH_LENGTH_EXCEEDED:
            SM_printf("SSL Verify PATH_LENGTH_EXCEEDED\n");
            break;
        case X509_V_ERR_CERT_UNTRUSTED:
            SM_printf("SSL Verify CERT_UNTRUSTED\n");
            break;
        case X509_V_ERR_CERT_REJECTED:
            SM_printf("SSL Verify CERT_REJECTED\n");
            break;
        case X509_V_ERR_UNABLE_TO_GET_CRL:
            SM_printf("SSL Verify UNABLE_TO_GET_CRL\n");
            break;
        case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
            SM_printf("SSL Verify UNABLE_TO_DECRYPT_CERT_SIGNATURE\n");
            break;
        case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
            SM_printf("SSL Verify UNABLE_TO_DECRYPT_CRL_SIGNATURE\n");
            break;
        case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
            SM_printf("SSL Verify UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY\n");
            break;
        case X509_V_ERR_CERT_SIGNATURE_FAILURE:
            SM_printf("SSL Verify CERT_SIGNATURE_FAILURE\n");
            break;
        case X509_V_ERR_CRL_SIGNATURE_FAILURE:
            SM_printf("SSL Verify CRL_SIGNATURE_FAILURE\n");
            break;
        case X509_V_ERR_CRL_NOT_YET_VALID:
            SM_printf("SSL Verify ERR_CRL_NOT_YET_VALID\n");
            break;
        case X509_V_ERR_CRL_HAS_EXPIRED:
            SM_printf("SSL Verify CRL_HAS_EXPIRED\n");
            break;
        case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
            SM_printf("SSL Verify ERROR_IN_CERT_NOT_BEFORE_FIELD\n");
            break;
        case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
            SM_printf("SSL Verify ERROR_IN_CERT_NOT_AFTER_FIELD\n");
            break;
        case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
            SM_printf("SSL Verify ERROR_IN_CRL_LAST_UPDATE_FIELD\n");
            break;
        case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
            SM_printf("SSL Verify ERROR_IN_CRL_NEXT_UPDATE_FIELD\n");
            break;
        case X509_V_ERR_OUT_OF_MEM:
            SM_printf("SSL Verify OUT_OF_MEM\n");
            break;
        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
            SM_printf("SSL Verify DEPTH_ZERO_SELF_SIGNED_CERT\n");
            break;
        case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
            SM_printf("SSL Verify SELF_SIGNED_CERT_IN_CHAIN\n");
            break;
        case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
            SM_printf("SSL Verify UNABLE_TO_VERIFY_LEAF_SIGNATURE\n");
            break;
        case X509_V_ERR_CERT_CHAIN_TOO_LONG:
            SM_printf("SSL Verify CERT_CHAIN_TOO_LONG\n");
            break;
        case X509_V_ERR_CERT_REVOKED:
            SM_printf("SSL Verify CERT_REVOKED\n");
            break;
        case X509_V_ERR_INVALID_CA:
            SM_printf("SSL Verify INVALID_CA\n");
            break;
        case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
            SM_printf("SSL Verify SUBJECT_ISSUER_MISMATCH\n");
            break;
        case X509_V_ERR_AKID_SKID_MISMATCH:
            SM_printf("SSL Verify AKID_SKID_MISMATCH\n");
            break;
        case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
            SM_printf("SSL Verify AKID_ISSUER_SERIAL_MISMATCH\n");
            break;
        case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
            SM_printf("SSL Verify UNABLE_TO_GET_CRL_ISSUER\n");
            break;
/*
        case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
        case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
        case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
        case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
        case X509_V_ERR_INVALID_NON_CA:
        case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
        case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
        case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
        case X509_V_ERR_INVALID_EXTENSION:
        case X509_V_ERR_INVALID_POLICY_EXTENSION:
        case X509_V_ERR_NO_EXPLICIT_POLICY:
        case X509_V_ERR_UNNESTED_RESOURCE:
        case X509_V_ERR_APPLICATION_VERIFICATION:
*/
    }
}

#if 0
void log_ssl_errors( )
{
   unsigned long err;
   char * sErrStr;
   SM_printf("log_ssl_errors -- \n");
   err = ERR_get_error();
   SM_printf("ERR_get_error Error code  %d\n",err);
   while( err != 0 ) 
   {
      SM_printf("Use NULL for error buffer so OpenSSL internal buffer is used.\n");
      // This internal buffer is not thread safe!
      sErrStr = (char *)ERR_error_string( err, NULL );
      if ( sErrStr != NULL ) 
         SM_printf("%lu - %s\n", err, sErrStr );
   }
}
#endif


X509 * pem_to_x509( char * pem )
{
   X509 * pX509 = NULL;
   BIO  * pBio  = NULL;

   /* Allocate BIO object*/
   pBio  = BIO_new( BIO_s_mem() );
   if ( pBio == NULL )
      return NULL;

   /* Put the raw certificate (char format) into the BIO object */
   BIO_write( pBio, pem, strlen(pem) );

   /* Parse the certificate */
   pX509 = (struct x509_st *)PEM_ASN1_read_bio( 
                (char *(*)())d2i_X509  /* DER to Internal conversion fn */
              , PEM_STRING_X509        /* PEM Marker string from pem.h  */
              , pBio                   /* BIO containing cert PEM data  */
              , NULL
              , NULL
              , NULL 
              );
   /* Free the BIO structure */
   BIO_free(pBio);
   /* Return the Cert */
   return pX509;
}


#define MAX_DEPTH 3

int my_verify_callback(int ok, X509_STORE_CTX *ctx)
{
   X509 *err_cert, *issuer;
   int err;
   int depth;
   char buf[256];
   SM_printf("my_verify_callback \n");
 
   err_cert = X509_STORE_CTX_get_current_cert(ctx);
   err      = X509_STORE_CTX_get_error(ctx);
   depth    = X509_STORE_CTX_get_error_depth(ctx);


   SM_printf("------------ Begin Verify Callback --------------\n");
   X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);
   if ( dump_cert_names ) 
   {
      SM_printf("verifying certificate: %s\n", buf);
      print_cert( err_cert );
      SM_printf("\n");
   }
   X509_NAME_oneline(X509_get_issuer_name(err_cert),buf,sizeof buf);
   if ( dump_cert_names ) 
   {
      SM_printf("issued by            : %s\n", buf);
      issuer = get_issuer( ctx );
      if ( issuer )
          print_cert( issuer );
      else
          SM_printf("No issuer yet\n");
      SM_printf("\n");
   }

   if ( !ok ) 
   {
      if ( depth >= MAX_DEPTH ) 
      {
         SM_printf("Verify callback: depth( %d ) exceeds %d\n", depth, MAX_DEPTH );
         X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
         ok = 0;
      }
      switch( ctx->error )
      {
      case X509_V_OK:
         SM_printf( "!ok but X509_V_OK?, just say OK\n");
         ok = 1;
         break;

      case X509_V_ERR_INVALID_PURPOSE:
         if ( verify_control_flags & ALLOW_INVALID_PURPOSE )
         {
            SM_printf("ignoring INVALID_PURPOSE error\n");
            X509_STORE_CTX_set_error(ctx,X509_V_OK);
            ok = 1;
         }
         break;

      case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
         if ( verify_control_flags & ALLOW_SELF_SIGNED_CERT_IN_CHAIN )
         {
            SM_printf("ignoring SELF_SIGNED_CERT_IN_CHAIN error\n");
            X509_STORE_CTX_set_error(ctx,X509_V_OK);
            ok = 1;
         }
         break;

      default:
         if ( ignore_all_verify_errors )
         {
            SM_printf("ignoring verify error (%d)", ctx->error);
            log_ssl_verify_errors( ctx->error );
            X509_STORE_CTX_set_error(ctx,X509_V_OK);
            ok = 1;
         }
         else
         {
            SM_printf("verify callback failing on ");
            log_ssl_verify_errors( ctx->error );
         }
         break;
      }    
   }

   SM_printf("------------ End Verify Callback --------------\n");
   return(ok);
}

void usage()
{
   SM_printf("ssltest [options]\n");
   SM_printf("    -s server_addr\n");
   SM_printf("    -p server_port\n");
   SM_printf("    -v             : disable client validation of server\n");
   SM_printf("    -f flags       : 1 to allow invalid purpose\n");
   SM_printf("                   : 2 to allow self signed cert in chain\n");
   SM_printf("                   : 32 to show certs being verified\n");
   SM_printf("    -o             : omit setting local trusted rootcert\n");
   SM_printf("    -i             : ignore all verify errors\n");

}

int ssltest(char *server, int port_num)
{
//   char    * server;
   int       port;
   SSL_CTX * sslctx  = NULL;  /* SSL Context */
   SSL     * sslcon  = NULL;  /* SSL Connection handle */
   int       s       = -1;         /* socket */
   int       err;
   int       e;
   BIO     * sbio    = NULL;
   //int       c;
   int       verify_peer = 1;
   //int       tmp;
   X509    * root_x509 = NULL;
   int       omit_rootcert = 0;
   SM_printf("ssltest: test function ---  \n");

  /* if ( argc < 3 )
   {
      usage();
      return 0;
   }
*/
    /* while ((c = getopt(argc, argv, "inovf:s:p:")) != -1)
         switch (c) {
         case 'v': verify_peer = 0; break;
         case 's': server = optarg; break;
         case 'p': port = atoi(optarg); break;
         case 'f': tmp = atoi(optarg); 
                   if ( tmp > 0 )
                      verify_control_flags |= (1 << (tmp-1));
                   break;
         case 'o': omit_rootcert = 1; break;
         case 'i': ignore_all_verify_errors = 1; 
                   verify_control_flags = 0xFFFFFFFF; 
                   break;
         case 'n': dump_cert_names = 1;
         case '?':
         case 'h': usage(argv[0]);           return 0;
         }
  */
//   server = "192.168.1.12";
   port = port_num;
//   port = 8090;
//   port = 12697;
   ignore_all_verify_errors = 1; 
   verify_control_flags = 0xFFFFFFFF; 
   verify_peer = 0;

   /* Check that port is valid */
   if ( port <= 0 )
   {
      SM_printf("invalid port %d\n", port );
      return 0;
   }

   /* Dump the Validation Flags */
   if ( verify_peer )
   {
      if ( ignore_all_verify_errors )
      {
         SM_printf("Verify Peer ignoring all validation errors\n");
      }
      else
      if ( verify_control_flags )
      {
         SM_printf("Verify Peer: (%x)\n",verify_control_flags);
         if ( verify_control_flags & ALLOW_INVALID_PURPOSE )
             SM_printf("           :Allow Invalid Purpose\n");
         if ( verify_control_flags & ALLOW_SELF_SIGNED_CERT_IN_CHAIN )
             SM_printf("           :Allow Self Signed Cert In Chain\n");
         if ( verify_control_flags & VERIFY_SHOW_CERTS )
             {
             dump_cert_names = 1;
             SM_printf("           :Show names of certs being verified\n");
             }
      }
      else
      {
         SM_printf("Verify Peer with no error exceptions\n");
      }
   }
   else
   {
      SM_printf("Peer Verification disabled\n");
   }

   do {

      /* Initialize OpenSSL */
	
      OpenSSL_add_all_algorithms();
      OpenSSL_add_all_digests();
      OpenSSL_add_all_ciphers();
      OpenSSL_add_ssl_algorithms();
	SSL_library_init();
      SSL_load_error_strings();

      /* Create an SSL Context */
      sslctx = SSL_CTX_new(TLSv1_client_method());
      if ( NULL == sslctx )
      {
         SM_printf("Failed to create SSL Context\n");
         break;
      }
      
SM_printf("SSL_CTX_new log ssl errors\n");
log_ssl_errors();

      /* Initialize the context */
      SSL_CTX_set_quiet_shutdown(sslctx,1);
      SSL_CTX_set_options(sslctx, 0);
      SSL_CTX_sess_set_cache_size(sslctx,128);

      /* Setup for Peer Validation */
      if ( verify_peer )
      {
         if ( !omit_rootcert )
         {
            SM_printf("setting local trusted rootcert\n");
            root_x509 = pem_to_x509( rootcert );
            if ( root_x509 )
               X509_STORE_add_cert( sslctx->cert_store, root_x509 );
            else
            {
               log_ssl_errors();
               SM_printf("Failed to convert rootcert to X509 structure in verify setup\n");
            }
         }
         else
         {
            SM_printf("omitted setting local trusted rootcert\n");
         }

         SM_printf("enabbling client validation of server SSL certificate\n");
         SSL_CTX_set_verify( sslctx
                           , SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
                           , my_verify_callback
                           );

         SSL_CTX_set_verify_depth( sslctx, 3 );
      }

      /* Create SSL Connection context */
      sslcon = SSL_new(sslctx);
      if ( sslcon == NULL ) 
      {
         SM_printf("SSL_new failed\n");
         break;
      }

SM_printf("SSL_new log ssl errors\n");
log_ssl_errors();

      /* Establish connection to the server */
      s = ip_connect( server, port );
      if ( -1 == s )
      {
         SM_printf("IP connection to %s on port %d Failed\n", server, port);
         break;
      }

      /* Wrap the connected socket in a BIO object so OpenSSL can use it */
      sbio = BIO_new_socket( s, BIO_NOCLOSE );
      if ( sbio == NULL ) 
      {
         SM_printf("Failed to create socket BIO\n");
         break;
      }

SM_printf("BIO_new_socket log ssl errors\n");
log_ssl_errors();

SM_printf("sslcon->type  %d\n",sslcon->type);
SM_printf("sslcon->version  %d\n",sslcon->version); //Protocol Version
SM_printf("sslcon->rwstate  %d\n",sslcon->rwstate);
SM_printf("sslcon->in_handshake  %d\n",sslcon->in_handshake);
SM_printf("sslcon->handshake_func  %d\n",sslcon->handshake_func);
SM_printf("sslcon->state  %d\n",sslcon->state);
SM_printf("sslcon->rstate  %d\n",sslcon->rstate);
SM_printf("sslcon->init_num  %d\n",sslcon->init_num); //amount read/written
SM_printf("sslcon->error  %d\n",sslcon->error);
SM_printf("sslcon->error_code  %d\n",sslcon->error_code); // Actual Error Code
SM_printf("sslcon->client_version  %d\n",sslcon->client_version);

      /* Give the connected socket to OpenSSL */
	SM_printf("Give the connected socket to OpenSSL\n");
      SSL_set_bio( sslcon, sbio, sbio );
      SSL_set_connect_state( sslcon );

      /* Perform the SSL handshake to complete the SSL connection */
      while( 1 )
      {
         /* do the SSL connection */
	   SM_printf("do the SSL connection\n");
         err = SSL_connect( sslcon );

	   SM_printf("SSL_connect status  %d\n", err);
         /* Check for success */
         if ( err > 0 )
         {
            log_ssl_errors();
            log_ssl_verify_errors( sslcon->verify_result );
            SM_printf("SSL_connect succeeded\n");
            break;
         }

         /* Error was returned */
         e = SSL_get_error( sslcon, err );
         if ( (SSL_ERROR_WANT_READ  != e) && (SSL_ERROR_WANT_WRITE != e) )
         {
            SM_printf("SSL_connect Error  %d\n", e);
		log_ssl_errors();
		int e = errno;
	      SM_printf("sockerrno to connect, err = %d (%s)\n", e, strerror(e) );
            log_ssl_verify_errors( sslcon->verify_result );
            SM_printf("SSL_connect Failed\n");

SM_printf("sslcon->type  %d\n",sslcon->type);
SM_printf("sslcon->version  %d\n",sslcon->version); //Protocol Version
SM_printf("sslcon->rwstate  %d\n",sslcon->rwstate);
SM_printf("sslcon->in_handshake  %d\n",sslcon->in_handshake);
SM_printf("sslcon->handshake_func  %d\n",sslcon->handshake_func);
SM_printf("sslcon->state  %d\n",sslcon->state);
SM_printf("sslcon->rstate  %d\n",sslcon->rstate);
SM_printf("sslcon->init_num  %d\n",sslcon->init_num); //amount read/written
SM_printf("sslcon->error  %d\n",sslcon->error);
SM_printf("sslcon->error_code  %d\n",sslcon->error_code); // Actual Error Code
SM_printf("sslcon->client_version  %d\n",sslcon->client_version);

            break;
         }

         /* OpenSSL wants to retry */
         SM_printf("Retry SSL_connect\n");
      }

      /* Connection has either been established, or it has failed */
   } while ( 0 );

   /* Free allocated resources */
   SM_printf("freeing resources\n");
   if ( sslcon )
   {
      SSL_shutdown( sslcon );
      shutdown( SSL_get_fd(sslcon), SHUT_RDWR );
      SSL_free( sslcon );
   }
   if ( s != -1 )
   {
      shutdown( s, SHUT_RDWR );
      close( s );
   }
   if ( sslctx )
      SSL_CTX_free( sslctx );
   if ( root_x509 )
      X509_free( root_x509 );

   EVP_cleanup();
   CRYPTO_cleanup_all_ex_data();
   ERR_remove_state(0);
   ERR_free_strings();

   return 0;
}



[-- Attachment #3: Type: text/plain, Size: 148 bytes --]

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-04-27 19:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-27 19:48 [ECOS] RE: RE: On Porting OpenSSL v1.0.0c amassa
     [not found] <20110425212037.JAAQV.41916.root@cdptpa-web03-z02>
     [not found] ` <03AEFB12CF391F45B74EC59D643A74510787B30FF7@DEFTHW99E24MSX.ww902.siemens.net>
2011-04-26 16:53   ` Anthony Massa
2011-04-27  7:07     ` Retallack, Mark

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).