ymbirtt
ymbirtt

Reputation: 1686

Populating an SSL_METHOD structure with OpenSSL in C

I'm trying to build a cipher suite with OpenSSL using the ANSI C API. It seems like what I need to do is create a new SSL_METHOD structure and populate it with various function pointers to the methods that it'll need to call. I've found the section of the source which defines the elements of an SSL_METHOD structure, but I've found no reference to what, precisely, each one is expected to contain for it to interface correctly with the rest of OpenSSL. OpenSSL has predefined functions which seem to build and populate one of these automatically, eg SSLv23_method, but I cannot find the source for these functions either.

Can anyone point me at some kind of resource which will tell me what goes behind each one of the pointers in an SSL_METHOD struct?

The following is a full list of all elements of an SSL_METHOD struct, the purposes of which I'd like to find.

int version;
int (*ssl_new)(SSL *s);
void (*ssl_clear)(SSL *s);
void (*ssl_free)(SSL *s);
int (*ssl_accept)(SSL *s);
int (*ssl_connect)(SSL *s);
int (*ssl_read)(SSL *s,void *buf,int len);
int (*ssl_peek)(SSL *s,void *buf,int len);
int (*ssl_write)(SSL *s,const void *buf,int len);
int (*ssl_shutdown)(SSL *s);
int (*ssl_renegotiate)(SSL *s);
int (*ssl_renegotiate_check)(SSL *s);
long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long
    max, int *ok);
int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, 
    int peek);
int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
int (*ssl_dispatch_alert)(SSL *s);
long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);
int (*ssl_pending)(const SSL *s);
int (*num_ciphers)(void);
const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
const struct ssl_method_st *(*get_ssl_method)(int version);
long (*get_timeout)(void);
struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
int (*ssl_version)(void);
long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));

Upvotes: 2

Views: 2580

Answers (1)

Chiara Hsieh
Chiara Hsieh

Reputation: 3393

I can provide you my experience in tracing OpenSSL code, in how they define a SSL_METHOD struct.

Take SSLv23_method for example, this method is defined in ssl.h

const SSL_METHOD *SSLv23_method(void);  /* SSLv3 but can rollback to v2 */

and is declared in s23_meth.c

IMPLEMENT_ssl23_meth_func(SSLv23_method,
        ssl23_accept,
        ssl23_connect,
        ssl23_get_method)

Then trace IMPLEMENT_ssl23_meth_func as below (in ssl_locl.h). It's a #define that designate each function implementations pointed by function pointers in a SSL_METHOD: SSLv23_method. For example, when (*ssl_new) function of this SSL_METHOD is called, it refers to tls1_new, and when (*ssl_connect) is called, it refers to s_accept, which is the second argument ssl23_accept function.

#define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \
const SSL_METHOD *func_name(void)  \
    { \
    static const SSL_METHOD func_name##_data= { \
    TLS1_2_VERSION, \
    tls1_new, \
    tls1_clear, \
    tls1_free, \
    s_accept, \
    s_connect, \
    ssl23_read, \
    ssl23_peek, \
    ssl23_write, \
    ssl_undefined_function, \
    ssl_undefined_function, \
    ssl_ok, \
    ssl3_get_message, \
    ssl3_read_bytes, \
    ssl3_write_bytes, \
    ssl3_dispatch_alert, \
    ssl3_ctrl, \
    ssl3_ctx_ctrl, \
    ssl23_get_cipher_by_char, \
    ssl23_put_cipher_by_char, \
    ssl_undefined_const_function, \
    ssl23_num_ciphers, \
    ssl23_get_cipher, \
    s_get_meth, \
    ssl23_default_timeout, \
    &ssl3_undef_enc_method, \
    ssl_undefined_void_function, \
    ssl3_callback_ctrl, \
    ssl3_ctx_callback_ctrl, \
    }; \
    return &func_name##_data; \
    }

You can trace each function for their purposes. By the way, a method is used to initialize ctx. You may have seen this,

meth=SSLv23_method();

and several lines later,

c_ctx=SSL_CTX_new(meth);

After that, c_ctx are passed as argument to some functions like SSL_CTX_set_cipher_list(c_ctx,cipher) or SSL_CTX_use_certificate_file(c_ctx,client_cert, SSL_FILETYPE_PEM). You may want to study SSL_CTX usage as well.

Upvotes: 6

Related Questions