1

I have two embedded systems running Angstrom Linux that are connected via a Ethernet cross-over cable. I'm developing a C program that will allow the two systems to communicate with each other.

When the two computers talk to each other they first need to verify the identity of the other and encrypt the connection. I'm trying to use openssl to accomplish the authentication and encryption but I'm not totally sure what to do. All the peer to peer questions are related to other languages or aren't related to openssl. I’ve been trying to modify the code from An Introduction to OpenSSL Programming http://www.linuxjournal.com/article/4822 to get my embedded systems working, but haven’t been successful. The in the SSL_CTX *initialize_ctx which is in common.c and also load_dh_params(ctx,file) in server.c seem to be the problem areas. Here is my code for common.c with some of my modifications.

SSL_CTX *initialize_ctx(keyfile,password)
char *keyfile;
char *password;
{
SSL_METHOD *meth;
SSL_CTX *ctx;
char buffer[200];
if (!bio_err)
{
    /* Global system initialization*/
    SSL_library_init();
    SSL_load_error_strings();

    /* An error write context */
    bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
}

debuglocation(__LINE__,__FILE__);
/* Set up a SIGPIPE handler */
signal(SIGPIPE,sigpipe_handle);

/* Create our context*/
meth=SSLv23_method();
ctx=SSL_CTX_new(meth);  

debuglocation(__LINE__,__FILE__);
/* Load our keys and certificates*/


//    if (!(SSL_CTX_use_certificate_chain_file(ctx,keyfile)))
//        berr_exit("Can't read certificate file");

debuglocation(__LINE__,__FILE__);

pass=password;
/* TODO need to put a password on the key*/
//SSL_CTX_set_default_passwd_cb(ctx,password_cb);
//if (!(SSL_CTX_use_PrivateKey_file(ctx,keyfile,SSL_FILETYPE_PEM)))

//http://www.openssl.org/docs/ssl/SSL_CTX_use_certificate.html#NOTES

if(!(SSL_CTX_use_RSAPrivateKey_file(ctx,"private.pem", SSL_FILETYPE_PEM)))
    berr_exit("Can't read priveate rsa");

debuglocation(__LINE__,__FILE__);
//berr_exit("Can't read key file");

//    /* Load the CAs we trust*/
//    if (!(SSL_CTX_load_verify_locations(ctx,
//                                        CA_LIST,0)))
//        berr_exit("Can't read CA list");
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
SSL_CTX_set_verify_depth(ctx,1);
#endif

return ctx;
}

And here is the server.c

void load_dh_params(ctx,file)
SSL_CTX *ctx;
char *file;
{
DH *ret=0;
BIO *bio;

//http://www.openssl.org/docs/crypto/BIO_s_file.html
// opens a file just like fopen with the second parameter as the type of open. Here it is read 'r'.
if ((bio=BIO_new_file(file,"r")) == NULL)
 berr_exit("Couldn't open DH file");

//http://www.openssl.org/docs/crypto/pem.html
ret=PEM_read_bio_DHparams(bio,NULL,NULL,
 NULL);
BIO_free(bio);


if(SSL_CTX_set_tmp_dh(ctx,ret)<0)
 berr_exit("Couldn't set DH parameters");
}

My debuglocation function looks like this.

int debuglocation(int line, char * file)
{
static char c = 'A';
printf("Made it to line %d in %s call it %c\n",line,file, c);
c++;
return 0;
}

So when I run all that I get from the server.

2535:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1075:

And this from the client.

SSL connect error
2616:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:596:

Also I’m not sure what ssl commands to use to make the needed certificates. It seemed like RSA would work well if both the embedded devices had one public and one priviate key, so I tried following http://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php and made a script to make them for me.

openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -outform PEM -pubout

Thanks in advance for the help. If you need more information please let me know. I think that answers to this question could be really helpful to anyone developing in C for an embedded system who needs some authentication.

Anthony

Anthony
  • 108
  • 10

2 Answers2

0

As the user that runs the comm process, do ssh_keygen.

Append the public part of the output, id_rsa.pub, to the ~/.ssh/authorized_keys on the other machine. Now you can run remote programs using ssh without logging in.

Edit. I suggested the above because of the hassle of working with certs. You need to have a trust store, correct directory permissions, etc. I think the first thing you're missing is loading the data on trusted certificates. See the link on how to do that. It's easier to check the authorization using the command line tools in openssl then to debug your program and get the SSL set up at the same time.

stark
  • 11,447
  • 3
  • 32
  • 46
  • When considering the problem there were two approaches. I could 1. fork,exec(ssh), and then parse the results, or 2. Make a secure socket using openssl. I chose openssl because it seemed to have more options and running exec(ssh) in a C program just didn't seem like a good practice. Was this a bad design decision? I use ssh to work on my embedded systems as they have no monitor or key board. – Anthony Apr 08 '12 at 05:30
0

I ended up using ssh rather than trying to use openssl. It did make life much simpler. Maybe when I have more time I will figure it out the other way.

Anthony
  • 108
  • 10