Hi, as per usual, I'm a relative OpenSSL newbie. I have managed to get client 
side apps working without too much effort, but I'm running into problems 
getting a server side app up and running under OpenBSD 3.0.

I created a certificate and key just for my sample app, whose source code is 
below. But I've haven't had much luck in locating clear instructions on which 
function calls to make in order to get an SSL connection up and running.

I've tried piecing together information found in the sample application 
s_server.c and the million and one sources scattered all over the place and 
build something straight forward, and less confusing, but I apparently 
failed. I'm getting the following error condition when ever a connection is 
established to my app:

        error:140C5022:lib(20):SSL_UNDEFINED_FUNCTION:reason(34)

>From what I've been able to determine, lib(20) is libssl.so.x.y (fill in your 
own values for x and y), but I haven't been able to figure out what 
reason(34) is. I'm assuming that SSL_UNDEFINED_FUNCTION might be the cause, 
but I have no clue what function is undefined. I did notice that the sample 
app is using a callback function. I didn't implement one, or make any calls 
to any functions that would require one. Is that what I'm missing here? If 
not, where am I going wrong? Also, on an unrelated note, can SSL connections 
be established over UDP datagrams instead of TCP streams?

The only function of the server app is to accept an SSL connection, print out 
some of the information about the connection, and quit if an error is 
encountered. Any way, here's the non-functional ugly source code:

#include <ssl/crypto.h>
#include <ssl/x509.h>
#include <ssl/pem.h>
#include <ssl/ssl.h>
#include <ssl/err.h>
#include <ssl/rand.h>
#include <ssl/ssl23.h>

#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>

int main() 
{
        static long long library_init_count = 0;
        static bool library_initialized = false;
        int sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP),conn;
        
        SSL_library_init();
        SSL_load_error_strings();
        library_initialized = true;
        SSLeay_add_ssl_algorithms();
        SSL_METHOD *sslmeth = SSLv23_client_method();
        SSL_CTX*        sslctx=SSL_CTX_new (sslmeth);
        if (sslctx==NULL)
                printf("SSL Context creation error\n");
        unsigned char buf[17];
        FILE *file=fopen("/dev/urandom","rt");
        while(RAND_status()!=1) {
                memset(buf,0,17);
                fread(buf,16,1,file);
                RAND_seed(buf,16);
        }
        fclose(file);
        struct sockaddr_in target,client;
        target.sin_family=AF_INET;
        target.sin_addr.s_addr=htonl(INADDR_ANY);
        target.sin_port=htons(1443);
        bind(sock,(struct sockaddr *)&target,sizeof(target));
        listen(sock,10);
        socklen_t sockln=0;
        SSL *ssl;
        SSL_CTX_set_options(sslctx,SSL_OP_SINGLE_DH_USE);
        SSL_CTX_use_certificate_file(sslctx,"serv.crt",SSL_FILETYPE_PEM);
        SSL_CTX_use_PrivateKey_file(sslctx,"serv.key",SSL_FILETYPE_PEM);
        if (!SSL_CTX_check_private_key(sslctx)) { //borrowed from the sample app
                printf("Private key does not match the certificate public key\n");
                return 0;
        }
        struct hostent *hptr=NULL;
        struct in_addr **pptr;
        bool quit=false;
        
        while (!quit) {
                memset(&client,0,sizeof(struct sockaddr_in));
                sockln=sizeof(struct sockaddr_in);
                conn=accept(sock,(struct sockaddr *)&client,&sockln);
                if (conn<0) {
                        printf("invalid socket\n");
                        continue;
                }
                printf("connection received\n");
                hptr=NULL;
                hptr=gethostbyaddr((char*)&client.sin_addr,sizeof(struct 
in_addr),AF_INET);
                long a=0;
                a=client.sin_addr.s_addr;
                printf("%ld:\t%ld.%ld.%ld.%ld\n",a,a&0xFF,(a>>8)&0xFF,(a>>16)&0xff,(a
>>24) & 0xff);
                if (client.sin_addr.s_addr==0) {
                        printf("client address is null, sockln %ld...!\n",sockln);
                        close(conn);
                        continue;
                }
        
                printf("creating new ssl.\n");
                ssl=SSL_new(sslctx);
                if (ssl) {
                        printf("setting session id context\n");
                        SSL_set_session_id_context(ssl,(unsigned char*
)sslctx,strlen((char*)sslctx));
                        printf("clearing ssl\n");
                        SSL_clear(ssl);
                        //the next item is done in my client, but done here because it 
seemed odd that
                        //I couldn't find it in the sample app.
                        printf("setting cipher list\n");
                        SSL_set_cipher_list(ssl,SSL_DEFAULT_CIPHER_LIST);
                        //commented out SSL_set_fd in favor of the BIO routines.
                        printf("setting file descriptor\n");
                        //SSL_set_fd(ssl,conn);
                        BIO *sbio;
                        sbio=BIO_new_socket(conn,BIO_NOCLOSE);
                        SSL_set_bio(ssl,sbio,sbio);
                        printf("setting ssl accept state\n");
                        SSL_set_accept_state(ssl);
                        int ret=0;
                        printf("ssl accepting...\n");
                        ret=SSL_accept(ssl);
                        printf("ret: %d\n",ret);
                        
                        switch(SSL_get_error(ssl,ret)) {
                                case SSL_ERROR_NONE: {
                                        printf("SSL Connected\n");
                                        SSL_CIPHER *cipher=SSL_get_current_cipher 
(ssl);
                                        printf ("SSL connection using %s\n", 
SSL_CIPHER_get_name(cipher));
                                        int usedbits=0,cipherbits=0;
                                        
usedbits=SSL_CIPHER_get_bits(cipher,&cipherbits);
                                        printf("SSL Cipher is %d bits, %d bits used.\
n",cipherbits,usedbits);
                                }break;
                                case SSL_ERROR_ZERO_RETURN: {
                                        printf("Error 0\n");
                                        quit=true;
                                }break;
                                default: {
                                        printf("Error %d\n",SSL_get_error(ssl,ret));
                                        char ert[150];
                                        ERR_error_string(ERR_get_error(),ert);
                                        printf("error: %s\n",ert);
                                        quit=true;
                                }
                        }
                        SSL_shutdown(ssl);
                        SSL_free(ssl);
                }
                close(conn);
        }
        close(sock);
        SSL_CTX_free(sslctx);
        return 0;
}
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to