@@ -11,6 +11,7 @@ typedef struct sqSSL {
1111
1212 char * certName ;
1313 char * peerName ;
14+ char * serverName ;
1415
1516 SSL_METHOD * method ;
1617 SSL_CTX * ctx ;
@@ -34,12 +35,12 @@ static sqSSL *sslFromHandle(sqInt handle) {
3435
3536/* sqCopyBioSSL: Copies data from a BIO into an out buffer */
3637sqInt sqCopyBioSSL (sqSSL * ssl , BIO * bio , char * dstBuf , sqInt dstLen ) {
37- int nbytes = BIO_ctrl_pending (bio );
38+ int nbytes = BIO_ctrl_pending (bio );
3839
39- if (ssl -> loglevel ) printf ("sqCopyBioSSL: %d bytes pending; buffer size %ld\n" ,
40- nbytes , (long )dstLen );
41- if (nbytes > dstLen ) return -1 ;
42- return BIO_read (bio , dstBuf , dstLen );
40+ if (ssl -> loglevel ) printf ("sqCopyBioSSL: %d bytes pending; buffer size %ld\n" ,
41+ nbytes , (long )dstLen );
42+ if (nbytes > dstLen ) return -1 ;
43+ return BIO_read (bio , dstBuf , dstLen );
4344}
4445
4546/* sqSetupSSL: Common SSL setup tasks */
@@ -60,16 +61,16 @@ sqInt sqSetupSSL(sqSSL *ssl, int server) {
6061 if (ssl -> certName ) {
6162 if (ssl -> loglevel ) printf ("sqSetupSSL: Using cert file %s\n" , ssl -> certName );
6263 if (SSL_CTX_use_certificate_file (ssl -> ctx , ssl -> certName , SSL_FILETYPE_PEM )<=0 )
63- ERR_print_errors_fp (stderr );
64+ ERR_print_errors_fp (stderr );
6465
6566 if (SSL_CTX_use_PrivateKey_file (ssl -> ctx , ssl -> certName , SSL_FILETYPE_PEM )<=0 )
66- ERR_print_errors_fp (stderr );
67+ ERR_print_errors_fp (stderr );
6768 }
6869
6970 /* Set up trusted CA */
7071 if (ssl -> loglevel ) printf ("sqSetupSSL: No root CA given; using default verify paths\n" );
7172 if (SSL_CTX_set_default_verify_paths (ssl -> ctx ) <=0 )
72- ERR_print_errors_fp (stderr );
73+ ERR_print_errors_fp (stderr );
7374
7475 if (ssl -> loglevel ) printf ("sqSetupSSL: Creating SSL\n" );
7576 ssl -> ssl = SSL_new (ssl -> ctx );
@@ -184,6 +185,13 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt
184185 if (ssl -> loglevel ) printf ("sqConnectSSL: BIO_write failed\n" );
185186 return SQSSL_GENERIC_ERROR ;
186187 }
188+
189+ /* if a server name is provided, use it */
190+ if (ssl -> serverName ) {
191+ if (ssl -> loglevel ) printf ("sqSetupSSL: Using server name %s\n" , ssl -> serverName );
192+ SSL_set_tlsext_host_name (ssl -> ssl , ssl -> serverName );
193+ }
194+
187195 if (ssl -> loglevel ) printf ("sqConnectSSL: SSL_connect\n" );
188196 result = SSL_connect (ssl -> ssl );
189197 if (result <= 0 ) {
@@ -206,8 +214,8 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt
206214 /* Fail if no cert received. */
207215 if (cert ) {
208216 X509_NAME_get_text_by_NID (X509_get_subject_name (cert ),
209- NID_commonName , peerName ,
210- sizeof (peerName ));
217+ NID_commonName , peerName ,
218+ sizeof (peerName ));
211219 if (ssl -> loglevel ) printf ("sqConnectSSL: peerName = %s\n" , peerName );
212220 ssl -> peerName = strdup (peerName );
213221 X509_free (cert );
@@ -289,18 +297,18 @@ sqInt sqAcceptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt
289297 if (ssl -> loglevel ) printf ("sqAcceptSSL: cert = %lx\n" , (long )cert );
290298
291299 if (cert ) {
292- X509_NAME_get_text_by_NID (X509_get_subject_name (cert ),
293- NID_commonName , peerName ,
294- sizeof (peerName ));
295- if (ssl -> loglevel ) printf ("sqAcceptSSL: peerName = %s\n" , peerName );
296- ssl -> peerName = strdup (peerName );
297- X509_free (cert );
298-
299- /* Check the result of verification */
300- result = SSL_get_verify_result (ssl -> ssl );
301- if (ssl -> loglevel ) printf ("sqAcceptSSL: SSL_get_verify_result = %d\n" , result );
302- /* FIXME: Figure out the actual failure reason */
303- ssl -> certFlags = result ? SQSSL_OTHER_ISSUE : SQSSL_OK ;
300+ X509_NAME_get_text_by_NID (X509_get_subject_name (cert ),
301+ NID_commonName , peerName ,
302+ sizeof (peerName ));
303+ if (ssl -> loglevel ) printf ("sqAcceptSSL: peerName = %s\n" , peerName );
304+ ssl -> peerName = strdup (peerName );
305+ X509_free (cert );
306+
307+ /* Check the result of verification */
308+ result = SSL_get_verify_result (ssl -> ssl );
309+ if (ssl -> loglevel ) printf ("sqAcceptSSL: SSL_get_verify_result = %d\n" , result );
310+ /* FIXME: Figure out the actual failure reason */
311+ ssl -> certFlags = result ? SQSSL_OTHER_ISSUE : SQSSL_OK ;
304312 } else {
305313 ssl -> certFlags = SQSSL_NO_CERTIFICATE ;
306314 }
@@ -348,11 +356,11 @@ sqInt sqDecryptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt
348356 if (nbytes != srcLen ) return SQSSL_GENERIC_ERROR ;
349357 nbytes = SSL_read (ssl -> ssl , dstBuf , dstLen );
350358 if (nbytes <= 0 ) {
351- int error = SSL_get_error (ssl -> ssl , nbytes );
352- if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_ZERO_RETURN ) {
353- return SQSSL_GENERIC_ERROR ;
354- }
355- nbytes = 0 ;
359+ int error = SSL_get_error (ssl -> ssl , nbytes );
360+ if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_ZERO_RETURN ) {
361+ return SQSSL_GENERIC_ERROR ;
362+ }
363+ nbytes = 0 ;
356364 }
357365 return nbytes ;
358366}
@@ -368,8 +376,9 @@ char* sqGetStringPropertySSL(sqInt handle, int propID) {
368376
369377 if (ssl == NULL ) return NULL ;
370378 switch (propID ) {
371- case SQSSL_PROP_PEERNAME : return ssl -> peerName ;
372- case SQSSL_PROP_CERTNAME : return ssl -> certName ;
379+ case SQSSL_PROP_PEERNAME : return ssl -> peerName ;
380+ case SQSSL_PROP_CERTNAME : return ssl -> certName ;
381+ case SQSSL_PROP_SERVERNAME : return ssl -> serverName ;
373382 default :
374383 if (ssl -> loglevel ) printf ("sqGetStringPropertySSL: Unknown property ID %d\n" , propID );
375384 return NULL ;
@@ -382,7 +391,7 @@ char* sqGetStringPropertySSL(sqInt handle, int propID) {
382391 handle - the ssl handle
383392 propID - the property id to retrieve
384393 propName - the property string
385- propLen - the length of the property string
394+ propLen - the length of the property string
386395 Returns: Non-zero if successful.
387396*/
388397sqInt sqSetStringPropertySSL (sqInt handle , int propID , char * propName , sqInt propLen ) {
@@ -392,15 +401,23 @@ sqInt sqSetStringPropertySSL(sqInt handle, int propID, char *propName, sqInt pro
392401 if (ssl == NULL ) return 0 ;
393402
394403 if (propLen ) {
395- property = calloc (1 , propLen + 1 );
396- memcpy (property , propName , propLen );
404+ property = malloc (propLen + 1 );
405+ memcpy (property , propName , propLen );
406+ property [propLen ] = '\0' ;
397407 };
398408
399409 if (ssl -> loglevel ) printf ("sqSetStringPropertySSL(%d): %s\n" , propID , property );
400410
401411 switch (propID ) {
402- case SQSSL_PROP_CERTNAME : ssl -> certName = property ; break ;
403- default :
412+ case SQSSL_PROP_CERTNAME :
413+ if (ssl -> certName ) free (ssl -> certName );
414+ ssl -> certName = property ;
415+ break ;
416+ case SQSSL_PROP_SERVERNAME :
417+ if (ssl -> serverName ) free (ssl -> serverName );
418+ ssl -> serverName = property ;
419+ break ;
420+ default :
404421 if (property ) free (property );
405422 if (ssl -> loglevel ) printf ("sqSetStringPropertySSL: Unknown property ID %d\n" , propID );
406423 return 0 ;
0 commit comments