Changeset 4697

Show
Ignore:
Timestamp:
02/26/07 15:58:02 (2 years ago)
Author:
morris
Message:

Add 128/192-bit AES

Make it easier to add additional ciphers in the code

Get complete error handling in connect/accept functions

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libwired/trunk/libwired/misc/wi-crypto.c

    r4680 r4697  
    542542static const EVP_CIPHER * _wi_cipher_cipher(wi_cipher_t *cipher) { 
    543543        switch(cipher->type) { 
     544                case WI_CIPHER_AES128:          return EVP_aes_128_cbc(); 
     545                case WI_CIPHER_AES192:          return EVP_aes_192_cbc(); 
    544546                case WI_CIPHER_AES256:          return EVP_aes_256_cbc(); 
    545547                case WI_CIPHER_BF128:           return EVP_bf_cbc(); 
     
    583585wi_string_t * wi_cipher_name(wi_cipher_t *cipher) { 
    584586        switch(cipher->type) { 
    585                 case WI_CIPHER_AES256:          return WI_STR("AES"); 
    586                 case WI_CIPHER_BF128:           return WI_STR("Blowfish"); 
    587                 case WI_CIPHER_3DES192:         return WI_STR("Triple DES"); 
     587                case WI_CIPHER_AES128: 
     588                case WI_CIPHER_AES192: 
     589                case WI_CIPHER_AES256: 
     590                        return WI_STR("AES"); 
     591 
     592                case WI_CIPHER_BF128: 
     593                        return WI_STR("Blowfish"); 
     594                 
     595                case WI_CIPHER_3DES192: 
     596                        return WI_STR("Triple DES"); 
    588597        } 
    589598         
  • libwired/trunk/libwired/misc/wi-crypto.h

    r4680 r4697  
    3535 
    3636enum _wi_cipher_type { 
     37        WI_CIPHER_AES128, 
     38        WI_CIPHER_AES192, 
    3739        WI_CIPHER_AES256, 
    3840        WI_CIPHER_BF128, 
  • libwired/trunk/libwired/misc/wi-error.c

    r4690 r4697  
    9393         
    9494        /* WI_ERROR_P7_INVALIDSPEC */ 
    95         "Invalid spec", 
     95        "Invalid specification", 
    9696        /* WI_ERROR_P7_INVALIDMESSAGE */ 
    9797        "Invalid message", 
     98        /* WI_ERROR_P7_UNKNOWNMESSAGE */ 
     99        "Unknown message", 
     100        /* WI_ERROR_P7_UNKNOWNFIELD */ 
     101        "Unknown field", 
     102        /* WI_ERROR_P7_HANDSHAKEFAILED */ 
     103        "Handshake failed", 
    98104         
    99105        /* WI_ERROR_REGEXP_NOSLASH */ 
     
    326332         
    327333        wi_release(error->string); 
    328  
    329         error->string = wi_string_init_with_format(wi_string_alloc(), WI_STR("%s: "), _wi_error_strings[error->code]); 
     334         
     335        error->string = wi_string_init(wi_string_alloc()); 
     336 
     337        if(strlen(_wi_error_strings[error->code]) > 0) 
     338                wi_string_append_format(error->string, WI_STR("%s: "), _wi_error_strings[error->code]); 
    330339         
    331340        va_start(ap, fmt); 
  • libwired/trunk/libwired/misc/wi-error.h

    r4690 r4697  
    6161        WI_ERROR_P7_INVALIDSPEC, 
    6262        WI_ERROR_P7_INVALIDMESSAGE, 
     63        WI_ERROR_P7_UNKNOWNMESSAGE, 
     64        WI_ERROR_P7_UNKNOWNFIELD, 
     65        WI_ERROR_P7_HANDSHAKEFAILED, 
    6366 
    6467        WI_ERROR_REGEXP_NOSLASH, 
  • libwired/trunk/libwired/p7/wi-p7-message.c

    r4696 r4697  
    134134        } 
    135135 
    136         wi_p7_message_set_name(p7_message, message_name); 
     136        if(!wi_p7_message_set_name(p7_message, message_name)) { 
     137                wi_release(p7_message); 
     138                 
     139                return NULL; 
     140        } 
    137141         
    138142        return p7_message; 
     
    388392                case WI_P7_ENUM: 
    389393                        if(wi_p7_message_get_enum_for_name(p7_message, &p7_enum, field_name)) 
    390                                 field_value = wi_string_with_format(WI_STR("%u"), p7_enum); 
     394                                field_value = wi_p7_spec_enum_name(p7_message->spec, wi_p7_spec_field_id(p7_message->spec, field_name), p7_enum); 
    391395                        break; 
    392396                         
     
    499503        field_id = wi_p7_spec_field_id(p7_message->spec, field_name); 
    500504         
    501         if(field_id == WI_P7_SPEC_FIELD_ID_NULL) 
     505        if(field_id == WI_P7_SPEC_FIELD_ID_NULL) { 
     506                wi_error_set_libwired_p7_error(WI_ERROR_P7_UNKNOWNFIELD, 
     507                        WI_STR("No id found for field \"%@\""), field_name); 
     508 
    502509                return false; 
     510        } 
    503511         
    504512        return _wi_p7_message_get_binary_buffer_for_reading_for_id(p7_message, field_id, 0, out_buffer, out_field_size); 
     
    512520        field_id = wi_p7_spec_field_id(p7_message->spec, field_name); 
    513521         
    514         if(field_id == WI_P7_SPEC_FIELD_ID_NULL) 
     522        if(field_id == WI_P7_SPEC_FIELD_ID_NULL) { 
     523                wi_error_set_libwired_p7_error(WI_ERROR_P7_UNKNOWNFIELD, 
     524                        WI_STR("No id found for field \"%@\""), field_name); 
     525                 
    515526                return false; 
     527        } 
    516528         
    517529        if(length > 0) 
     
    678690#pragma mark - 
    679691 
    680 void wi_p7_message_set_name(wi_p7_message_t *p7_message, wi_string_t *name) { 
     692wi_boolean_t wi_p7_message_set_name(wi_p7_message_t *p7_message, wi_string_t *name) { 
     693        if(p7_message->serialization == WI_P7_BINARY) { 
     694                p7_message->binary_id = wi_p7_spec_message_id(p7_message->spec, name); 
     695                 
     696                if(p7_message->binary_id == WI_P7_SPEC_MESSAGE_ID_NULL) { 
     697                        wi_error_set_libwired_p7_error(WI_ERROR_P7_UNKNOWNMESSAGE, 
     698                                WI_STR("No id found for message \"%@\""), name); 
     699 
     700                        return false; 
     701                } 
     702                 
     703                wi_write_swap_host_to_big_int32(p7_message->binary_buffer, 0, p7_message->binary_id); 
     704        } else { 
     705                xmlSetProp(p7_message->xml_root_node, (xmlChar *) "name", (xmlChar *) wi_string_cstring(name)); 
     706        } 
     707         
    681708        wi_retain(name); 
    682709        wi_release(p7_message->name); 
     
    684711        p7_message->name = name; 
    685712         
    686         if(p7_message->serialization == WI_P7_BINARY) { 
    687                 p7_message->binary_id = wi_p7_spec_message_id(p7_message->spec, p7_message->name); 
    688                 wi_write_swap_host_to_big_int32(p7_message->binary_buffer, 0, p7_message->binary_id); 
    689         } else { 
    690                 xmlSetProp(p7_message->xml_root_node, (xmlChar *) "name", (xmlChar *) wi_string_cstring(p7_message->name)); 
    691         } 
     713        return true; 
    692714} 
    693715 
  • libwired/trunk/libwired/p7/wi-p7-message.h

    r4693 r4697  
    7979WI_EXPORT wi_p7_message_t *                     wi_p7_message_init_with_name(wi_p7_message_t *, wi_string_t *, wi_p7_socket_t *); 
    8080 
    81 WI_EXPORT void                                        wi_p7_message_set_name(wi_p7_message_t *, wi_string_t *); 
     81WI_EXPORT wi_boolean_t                                wi_p7_message_set_name(wi_p7_message_t *, wi_string_t *); 
    8282WI_EXPORT wi_string_t *                         wi_p7_message_name(wi_p7_message_t *); 
    8383 
  • libwired/trunk/libwired/p7/wi-p7-socket.c

    r4696 r4697  
    3333#include <wired/wi-byteorder.h> 
    3434#include <wired/wi-crypto.h> 
     35#include <wired/wi-error.h> 
    3536#include <wired/wi-log.h> 
    3637#include <wired/wi-p7-message.h> 
     
    5051#include <zlib.h> 
    5152 
    52 #define _WI_P7_SOCKET_XML_MAGIC                         0x3C3F786D 
    53 #define _WI_P7_SOCKET_BINARY_MAGIC_SIZE         58 
    54  
    55 #define _WI_P7_SOCKET_OPTIONS_ENCRYPTION_ENABLED(options)       \ 
    56         (((options) & WI_P7_ENCRYPTION_RSA_AES256_SHA1) ||              \ 
     53#define _WI_P7_SOCKET_XML_MAGIC                                                         0x3C3F786D 
     54#define _WI_P7_SOCKET_BINARY_MAGIC_SIZE                                         58 
     55 
     56#define _WI_P7_COMPRESSION_DEFLATE                                                      0 
     57#define _WI_P7_ENCRYPTION_RSA_AES128_SHA1                                       0        
     58#define _WI_P7_ENCRYPTION_RSA_AES192_SHA1                                       1 
     59#define _WI_P7_ENCRYPTION_RSA_AES256_SHA1                                       2 
     60#define _WI_P7_ENCRYPTION_RSA_BF128_SHA1                                        3 
     61#define _WI_P7_ENCRYPTION_RSA_3DES192_SHA1                                      4 
     62 
     63#define _WI_P7_COMPRESSION_ENABLED(options)                                     \ 
     64        (((options) & WI_P7_COMPRESSION_DEFLATE)) 
     65 
     66#define _WI_P7_ENCRYPTION_ENABLED(options)                                      \ 
     67        (((options) & WI_P7_ENCRYPTION_RSA_AES128_SHA1) ||              \ 
     68         ((options) & WI_P7_ENCRYPTION_RSA_AES192_SHA1) ||              \ 
     69         ((options) & WI_P7_ENCRYPTION_RSA_AES256_SHA1) ||              \ 
    5770         ((options) & WI_P7_ENCRYPTION_RSA_BF128_SHA1) ||               \ 
    5871         ((options) & WI_P7_ENCRYPTION_RSA_3DES192_SHA1)) 
    5972 
     73#define _WI_P7_COMPRESSION_ENUM_TO_OPTIONS(flag)                        \ 
     74        ((flag) == _WI_P7_COMPRESSION_DEFLATE ?                                 \ 
     75                WI_P7_COMPRESSION_DEFLATE :     -1) 
     76 
     77#define _WI_P7_ENCRYPTION_ENUM_TO_OPTIONS(flag)                         \ 
     78        ((flag) == _WI_P7_ENCRYPTION_RSA_AES128_SHA1 ?                  \ 
     79                WI_P7_ENCRYPTION_RSA_AES128_SHA1 :                                      \ 
     80         (flag) == _WI_P7_ENCRYPTION_RSA_AES192_SHA1 ?                  \ 
     81                WI_P7_ENCRYPTION_RSA_AES192_SHA1 :                                      \ 
     82         (flag) == _WI_P7_ENCRYPTION_RSA_AES256_SHA1 ?                  \ 
     83                WI_P7_ENCRYPTION_RSA_AES256_SHA1 :                                      \ 
     84         (flag) == _WI_P7_ENCRYPTION_RSA_BF128_SHA1 ?                   \ 
     85                WI_P7_ENCRYPTION_RSA_BF128_SHA1 :                                       \ 
     86         (flag) == _WI_P7_ENCRYPTION_RSA_3DES192_SHA1 ?                 \ 
     87                WI_P7_ENCRYPTION_RSA_3DES192_SHA1 : -1) 
     88 
     89#define _WI_P7_COMPRESSION_OPTIONS_TO_ENUM(options)                     \ 
     90        ((options) & WI_P7_COMPRESSION_DEFLATE ?                                \ 
     91                _WI_P7_COMPRESSION_DEFLATE : -1) 
     92 
     93#define _WI_P7_ENCRYPTION_OPTIONS_TO_ENUM(options)                      \ 
     94        ((options) & WI_P7_ENCRYPTION_RSA_AES128_SHA1 ?                 \ 
     95                _WI_P7_ENCRYPTION_RSA_AES128_SHA1 :                                     \ 
     96         (options) & WI_P7_ENCRYPTION_RSA_AES192_SHA1 ?                 \ 
     97                _WI_P7_ENCRYPTION_RSA_AES192_SHA1 :                                     \ 
     98         (options) & WI_P7_ENCRYPTION_RSA_AES256_SHA1 ?                 \ 
     99                _WI_P7_ENCRYPTION_RSA_AES256_SHA1 :                                     \ 
     100         (options) & WI_P7_ENCRYPTION_RSA_BF128_SHA1 ?                  \ 
     101                _WI_P7_ENCRYPTION_RSA_BF128_SHA1 :                                      \ 
     102         (options) & WI_P7_ENCRYPTION_RSA_3DES192_SHA1 ?                \ 
     103                _WI_P7_ENCRYPTION_RSA_3DES192_SHA1 : -1) 
     104 
     105#define _WI_P7_ENCRYPTION_OPTIONS_TO_CIPHER(options)            \ 
     106        ((options) & WI_P7_ENCRYPTION_RSA_AES128_SHA1 ?                 \ 
     107                WI_CIPHER_AES128 :                                                                      \ 
     108         (options) & WI_P7_ENCRYPTION_RSA_AES192_SHA1 ?                 \ 
     109                WI_CIPHER_AES192 :                                                                      \ 
     110         (options) & WI_P7_ENCRYPTION_RSA_AES256_SHA1 ?                 \ 
     111                WI_CIPHER_AES256 :                                                                      \ 
     112         (options) & WI_P7_ENCRYPTION_RSA_BF128_SHA1 ?                  \ 
     113                WI_CIPHER_BF128 :                                                                       \ 
     114         (options) & WI_P7_ENCRYPTION_RSA_3DES192_SHA1 ?                \ 
     115                WI_CIPHER_3DES192 : -1) 
     116 
    60117 
    61118struct _wi_p7_socket { 
     
    65122         
    66123        wi_p7_spec_t                                                    *spec; 
     124        wi_string_t                                                             *name; 
     125        double                                                                  version; 
    67126         
    68127        wi_p7_serialization_t                                   serialization; 
     
    101160static wi_boolean_t                                                     _wi_p7_socket_send_compatibility_check(wi_p7_socket_t *, wi_time_interval_t); 
    102161static wi_boolean_t                                                     _wi_p7_socket_receive_compatibility_check(wi_p7_socket_t *, wi_time_interval_t); 
    103 static wi_cipher_type_t                                         _wi_p7_socket_cipher(wi_p7_socket_t *); 
    104162static wi_boolean_t                                                     _wi_p7_socket_configure_compression_streams(wi_p7_socket_t *); 
    105163static wi_boolean_t                                                     _wi_p7_socket_xcompress_buffer(wi_p7_socket_t *, _wi_p7_socket_compression_t, const void *, uint32_t, void **, uint32_t *); 
     
    172230         
    173231        wi_release(p7_socket->socket); 
     232        wi_release(p7_socket->spec); 
     233        wi_release(p7_socket->name); 
    174234        wi_release(p7_socket->rsa); 
    175235        wi_release(p7_socket->cipher); 
     
    242302 
    243303static wi_boolean_t _wi_p7_socket_connect_handshake(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, wi_p7_options_t options) { 
    244         wi_string_t                     *protocol_name; 
    245304        wi_p7_message_t         *p7_message; 
    246         wi_p7_double_t          version, protocol_version
    247         wi_p7_uint32_t         compression, encryption
     305        wi_p7_double_t          version
     306        wi_p7_enum_t           flag
    248307         
    249308        p7_message = wi_p7_message_with_name(WI_STR("p7.handshake"), p7_socket); 
    250309         
    251         if(!p7_message) { 
    252                 wi_log_info(WI_STR("couldn't create message")); 
    253  
    254                 return false; 
    255         } 
    256  
    257         wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(wi_p7_spec_builtin_spec()), WI_STR("p7.handshake.version")); 
    258         wi_p7_message_set_string_for_name(p7_message, wi_p7_spec_name(p7_socket->spec), WI_STR("p7.handshake.protocol_name")); 
    259         wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(p7_socket->spec), WI_STR("p7.handshake.protocol_version")); 
     310        if(!p7_message) 
     311                return false; 
     312 
     313        if(!wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(wi_p7_spec_builtin_spec()), WI_STR("p7.handshake.version"))) 
     314                return false; 
     315         
     316        if(!wi_p7_message_set_string_for_name(p7_message, wi_p7_spec_name(p7_socket->spec), WI_STR("p7.handshake.protocol_name"))) 
     317                return false; 
     318         
     319        if(!wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(p7_socket->spec), WI_STR("p7.handshake.protocol_version"))) 
     320                return false; 
    260321         
    261322        if(p7_socket->serialization == WI_P7_BINARY) { 
    262                 if(options & WI_P7_COMPRESSION_DEFLATE) 
    263                    wi_p7_message_set_enum_for_name(p7_message, 0, WI_STR("p7.handshake.compression")); 
    264                  
    265                 if(options & WI_P7_ENCRYPTION_RSA_AES256_SHA1) 
    266                         wi_p7_message_set_enum_for_name(p7_message, 0, WI_STR("p7.handshake.encryption")); 
    267                 else if(options & WI_P7_ENCRYPTION_RSA_BF128_SHA1) 
    268                         wi_p7_message_set_enum_for_name(p7_message, 1, WI_STR("p7.handshake.encryption")); 
    269                 else if(options & WI_P7_ENCRYPTION_RSA_3DES192_SHA1) 
    270                         wi_p7_message_set_enum_for_name(p7_message, 2, WI_STR("p7.handshake.encryption")); 
    271         } 
    272          
    273         if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) { 
    274                 wi_log_warn(WI_STR("message write failed")); 
    275  
    276                 return false; 
    277         } 
     323                if(_WI_P7_COMPRESSION_ENABLED(options)) { 
     324                        if(!wi_p7_message_set_enum_for_name(p7_message, 
     325                                                                                                _WI_P7_COMPRESSION_OPTIONS_TO_ENUM(options), 
     326                                                                                                WI_STR("p7.handshake.compression"))) { 
     327                                return false; 
     328                        } 
     329                } 
     330                 
     331                if(_WI_P7_ENCRYPTION_ENABLED(options)) { 
     332                        if(!wi_p7_message_set_enum_for_name(p7_message, 
     333                                                                                                _WI_P7_ENCRYPTION_OPTIONS_TO_ENUM(options), 
     334                                                                                                WI_STR("p7.handshake.encryption"))) { 
     335                                return false; 
     336                        } 
     337                } 
     338        } 
     339         
     340        if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) 
     341                return false; 
    278342         
    279343        p7_message = wi_p7_socket_read_message(p7_socket, timeout); 
    280344         
    281         if(!p7_message) { 
    282                 wi_log_warn(WI_STR("message read failed")); 
    283                  
    284                 return false; 
    285         } 
     345        if(!p7_message) 
     346                return false; 
    286347 
    287348        if(!wi_is_equal(p7_message->name, WI_STR("p7.handshake.reply"))) { 
    288                 wi_log_warn(WI_STR("wrong message: %@"), p7_message->name); 
     349                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     350                        WI_STR("Message should be \"p7.handshake.reply\", not \"%@\""), 
     351                        p7_message->name); 
    289352                 
    290353                return false; 
     
    292355         
    293356        if(!wi_p7_message_get_double_for_name(p7_message, &version, WI_STR("p7.handshake.version"))) { 
    294                 wi_log_warn(WI_STR("missing keys: version")); 
     357                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     358                        WI_STR("Message has no \"p7.handshake.version\" field")); 
    295359                 
    296360                return false; 
     
    298362 
    299363        if(version != wi_p7_spec_version(wi_p7_spec_builtin_spec())) { 
    300                 wi_log_warn(WI_STR("version mismatch (%.1f != %.1f)"), version, wi_p7_spec_version(wi_p7_spec_builtin_spec())); 
    301                  
    302                 return false; 
    303         } 
    304          
    305         protocol_name = wi_p7_message_string_for_name(p7_message, WI_STR("p7.handshake.protocol_name")); 
    306          
    307         if(!protocol_name) { 
    308                 wi_log_warn(WI_STR("missing keys: protocol_name")); 
    309                  
    310                 return false; 
    311         } 
    312          
    313         if(!wi_p7_message_get_double_for_name(p7_message, &protocol_version, WI_STR("p7.handshake.protocol_version"))) { 
    314                 wi_log_warn(WI_STR("missing keys: protocol_version")); 
    315                  
    316                 return false; 
    317         } 
    318          
    319         p7_socket->local_compatibility_check = !wi_p7_spec_is_compatible_with_protocol(p7_socket->spec, protocol_name, protocol_version); 
    320  
    321         if(wi_p7_message_get_uint32_for_name(p7_message, &compression, WI_STR("p7.handshake.compression"))) { 
    322                 if(compression == 0) 
    323                         p7_socket->options |= WI_P7_COMPRESSION_DEFLATE; 
    324         } 
    325          
    326         if(wi_p7_message_get_uint32_for_name(p7_message, &encryption, WI_STR("p7.handshake.encryption"))) { 
    327                 if(encryption == 0) 
    328                         p7_socket->options |= WI_P7_ENCRYPTION_RSA_AES256_SHA1; 
    329                 else if(encryption == 1) 
    330                         p7_socket->options |= WI_P7_ENCRYPTION_RSA_BF128_SHA1; 
    331                 else if(encryption == 2) 
    332                         p7_socket->options |= WI_P7_ENCRYPTION_RSA_3DES192_SHA1; 
     364                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     365                        WI_STR("Remote P7 protocol %.1f is not compatible"), 
     366                        version); 
     367                 
     368                return false; 
     369        } 
     370         
     371        p7_socket->name = wi_retain(wi_p7_message_string_for_name(p7_message, WI_STR("p7.handshake.protocol_name"))); 
     372         
     373        if(!p7_socket->name) { 
     374                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     375                        WI_STR("Message has no \"p7.handshake.protocol_name\" field")); 
     376                 
     377                return false; 
     378        } 
     379         
     380        if(!wi_p7_message_get_double_for_name(p7_message, &p7_socket->version, WI_STR("p7.handshake.protocol_version"))) { 
     381                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     382                        WI_STR("Message has no \"p7.handshake.protocol_version\" field")); 
     383                 
     384                return false; 
     385        } 
     386         
     387        p7_socket->local_compatibility_check = !wi_p7_spec_is_compatible_with_protocol(p7_socket->spec, p7_socket->name, p7_socket->version); 
     388 
     389        if(p7_socket->serialization == WI_P7_BINARY) { 
     390                if(wi_p7_message_get_enum_for_name(p7_message, &flag, WI_STR("p7.handshake.compression"))) 
     391                        p7_socket->options |= _WI_P7_COMPRESSION_ENUM_TO_OPTIONS(flag); 
     392         
     393                if(wi_p7_message_get_uint32_for_name(p7_message, &flag, WI_STR("p7.handshake.encryption"))) 
     394                        p7_socket->options |= _WI_P7_ENCRYPTION_ENUM_TO_OPTIONS(flag); 
    333395        } 
    334396         
     
    338400        p7_message = wi_p7_message_with_name(WI_STR("p7.handshake.acknowledge"), p7_socket); 
    339401         
    340         if(!p7_message) { 
    341                 wi_log_info(WI_STR("couldn't create message")); 
    342                  
    343                 return false; 
    344         } 
    345          
    346         if(p7_socket->local_compatibility_check) 
    347                 wi_p7_message_set_bool_for_name(p7_message, true, WI_STR("p7.handshake.compatibility_check")); 
    348  
    349         if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) { 
    350                 wi_log_warn(WI_STR("message write failed")); 
    351  
    352                 return false; 
    353         } 
     402        if(!p7_message) 
     403                return false; 
     404         
     405        if(p7_socket->local_compatibility_check) { 
     406                if(!wi_p7_message_set_bool_for_name(p7_message, true, WI_STR("p7.handshake.compatibility_check"))) 
     407                        return false; 
     408        } 
     409 
     410        if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) 
     411                return false; 
    354412         
    355413        return true; 
     
    359417 
    360418static wi_boolean_t _wi_p7_socket_accept_handshake(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, wi_p7_options_t options) { 
    361         wi_string_t                     *protocol_name; 
    362419        wi_p7_message_t         *p7_message; 
    363         wi_p7_double_t          version, protocol_version; 
    364         wi_p7_enum_t            compression, encryption; 
     420        wi_p7_double_t          version; 
     421        wi_p7_enum_t            flag; 
     422        wi_p7_options_t         client_options; 
    365423         
    366424        p7_message = wi_p7_socket_read_message(p7_socket, timeout); 
    367425         
    368         if(!p7_message) { 
    369                 wi_log_warn(WI_STR("message read failed")); 
    370                  
    371                 return false; 
    372         } 
     426        if(!p7_message) 
     427                return false; 
    373428 
    374429        if(!wi_is_equal(p7_message->name, WI_STR("p7.handshake"))) { 
    375                 wi_log_warn(WI_STR("wrong message (%@ != %@)"), p7_message->name, WI_STR("p7.handshake")); 
     430                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     431                        WI_STR("Message should be \"p7.handshake\", not \"%@\""), 
     432                        p7_message->name); 
    376433                 
    377434                return false; 
     
    379436         
    380437        if(!wi_p7_message_get_double_for_name(p7_message, &version, WI_STR("p7.handshake.version"))) { 
    381                 wi_log_warn(WI_STR("missing keys: version")); 
    382                  
    383                 return false; 
    384         } 
    385  
     438                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     439                        WI_STR("Message has no \"p7.handshake.version\" field")); 
     440                 
     441                return false; 
     442        } 
     443         
    386444        if(version != wi_p7_spec_version(wi_p7_spec_builtin_spec())) { 
    387                 wi_log_warn(WI_STR("version mismatch (%u != %u)"), version, wi_p7_spec_version(wi_p7_spec_builtin_spec())); 
    388                  
    389                 return false; 
    390         } 
    391          
    392         protocol_name = wi_p7_message_string_for_name(p7_message, WI_STR("p7.handshake.protocol_name")); 
    393          
    394         if(!protocol_name) { 
    395                 wi_log_warn(WI_STR("missing keys: protocol_name")); 
    396                  
    397                 return false; 
    398         } 
    399          
    400         if(!wi_p7_message_get_double_for_name(p7_message, &protocol_version, WI_STR("p7.handshake.protocol_version"))) { 
    401                 wi_log_warn(WI_STR("missing keys: protocol_version")); 
    402                  
    403                 return false; 
    404         } 
    405  
    406         p7_socket->local_compatibility_check = !wi_p7_spec_is_compatible_with_protocol(p7_socket->spec, protocol_name, protocol_version); 
     445                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     446                        WI_STR("Remote P7 protocol %.1f is not compatible"), 
     447                        version); 
     448 
     449                return false; 
     450        } 
     451         
     452        p7_socket->name = wi_retain(wi_p7_message_string_for_name(p7_message, WI_STR("p7.handshake.protocol_name"))); 
     453         
     454        if(!p7_socket->name) { 
     455                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     456                        WI_STR("Message has no \"p7.handshake.protocol_name\" field")); 
     457                 
     458                return false; 
     459        } 
     460         
     461        if(!wi_p7_message_get_double_for_name(p7_message, &p7_socket->version, WI_STR("p7.handshake.protocol_version"))) { 
     462                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     463                        WI_STR("Message has no \"p7.handshake.protocol_version\" field")); 
     464                 
     465                return false; 
     466        } 
     467 
     468        p7_socket->local_compatibility_check = !wi_p7_spec_is_compatible_with_protocol(p7_socket->spec, p7_socket->name, p7_socket->version); 
    407469 
    408470        if(p7_socket->serialization == WI_P7_BINARY) { 
    409                 if(wi_p7_message_get_enum_for_name(p7_message, &compression, WI_STR("p7.handshake.compression"))) { 
    410                         if(compression == 0 && options & WI_P7_COMPRESSION_DEFLATE) 
    411                                p7_socket->options |= WI_P7_COMPRESSION_DEFLATE; 
    412                 } 
    413                  
    414                 if(wi_p7_message_get_enum_for_name(p7_message, &encryption, WI_STR("p7.handshake.encryption"))) { 
    415                        if(encryption == 0 && options & WI_P7_ENCRYPTION_RSA_AES256_SHA1) 
    416                                p7_socket->options |= WI_P7_ENCRYPTION_RSA_AES256_SHA1; 
    417                         else if(encryption == 1 && options & WI_P7_ENCRYPTION_RSA_BF128_SHA1) 
    418                                 p7_socket->options |= WI_P7_ENCRYPTION_RSA_BF128_SHA1; 
    419                         else if(encryption == 2 && options & WI_P7_ENCRYPTION_RSA_3DES192_SHA1
    420                                 p7_socket->options |= WI_P7_ENCRYPTION_RSA_3DES192_SHA1
     471                if(wi_p7_message_get_enum_for_name(p7_message, &flag, WI_STR("p7.handshake.compression"))) { 
     472                        client_options = _WI_P7_COMPRESSION_ENUM_TO_OPTIONS(flag); 
     473                         
     474                       if(options & client_options) 
     475                               p7_socket->options |= client_options; 
     476                } 
     477                 
     478                if(wi_p7_message_get_enum_for_name(p7_message, &flag, WI_STR("p7.handshake.encryption"))) { 
     479                        client_options = _WI_P7_ENCRYPTION_ENUM_TO_OPTIONS(flag); 
     480 
     481                        if(options & client_options
     482                                p7_socket->options |= client_options
    421483                } 
    422484        } 
     
    424486        p7_message = wi_p7_message_with_name(WI_STR("p7.handshake.reply"), p7_socket); 
    425487 
    426         if(!p7_message) { 
    427                 wi_log_info(WI_STR("couldn't create message")); 
    428                  
    429                 return false; 
    430         } 
    431          
    432         wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(wi_p7_spec_builtin_spec()), WI_STR("p7.handshake.version")); 
    433         wi_p7_message_set_string_for_name(p7_message, wi_p7_spec_name(p7_socket->spec), WI_STR("p7.handshake.protocol_name")); 
    434         wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(p7_socket->spec), WI_STR("p7.handshake.protocol_version")); 
    435          
    436         if(p7_socket->options & WI_P7_COMPRESSION_DEFLATE) 
    437            wi_p7_message_set_uint32_for_name(p7_message, 0, WI_STR("p7.handshake.compression")); 
    438          
    439         if(p7_socket->options & WI_P7_ENCRYPTION_RSA_AES256_SHA1) 
    440                 wi_p7_message_set_uint32_for_name(p7_message, 0, WI_STR("p7.handshake.encryption")); 
    441         else if(p7_socket->options & WI_P7_ENCRYPTION_RSA_BF128_SHA1) 
    442                 wi_p7_message_set_uint32_for_name(p7_message, 1, WI_STR("p7.handshake.encryption")); 
    443         else if(p7_socket->options & WI_P7_ENCRYPTION_RSA_3DES192_SHA1) 
    444                 wi_p7_message_set_uint32_for_name(p7_message, 2, WI_STR("p7.handshake.encryption")); 
    445          
    446         if(p7_socket->local_compatibility_check) 
    447                 wi_p7_message_set_bool_for_name(p7_message, true, WI_STR("p7.handshake.compatibility_check")); 
    448  
    449         if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) { 
    450                 wi_log_warn(WI_STR("message read failed")); 
    451  
    452                 return false; 
    453         } 
     488        if(!p7_message) 
     489                return false; 
     490         
     491        if(!wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(wi_p7_spec_builtin_spec()), WI_STR("p7.handshake.version"))) 
     492                return false; 
     493         
     494        if(!wi_p7_message_set_string_for_name(p7_message, wi_p7_spec_name(p7_socket->spec), WI_STR("p7.handshake.protocol_name"))) 
     495                return false; 
     496         
     497        if(!wi_p7_message_set_double_for_name(p7_message, wi_p7_spec_version(p7_socket->spec), WI_STR("p7.handshake.protocol_version"))) 
     498                return false; 
     499         
     500        if(p7_socket->serialization == WI_P7_BINARY) { 
     501                if(_WI_P7_COMPRESSION_ENABLED(p7_socket->options)) { 
     502                        if(!wi_p7_message_set_enum_for_name(p7_message, 
     503                                                                                                _WI_P7_COMPRESSION_OPTIONS_TO_ENUM(p7_socket->options), 
     504                                                                                                WI_STR("p7.handshake.compression"))) { 
     505                                return false; 
     506                        } 
     507                } 
     508 
     509                if(_WI_P7_ENCRYPTION_ENABLED(p7_socket->options)) { 
     510                        if(!wi_p7_message_set_enum_for_name(p7_message, 
     511                                                                                                _WI_P7_ENCRYPTION_OPTIONS_TO_ENUM(p7_socket->options), 
     512                                                                                                WI_STR("p7.handshake.encryption"))) { 
     513                                return false; 
     514                        } 
     515                } 
     516        } 
     517         
     518        if(p7_socket->local_compatibility_check) { 
     519                if(!wi_p7_message_set_bool_for_name(p7_message, true, WI_STR("p7.handshake.compatibility_check"))) 
     520                        return false; 
     521        } 
     522 
     523        if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) 
     524                return false; 
    454525 
    455526        p7_message = wi_p7_socket_read_message(p7_socket, timeout); 
    456527         
    457         if(!p7_message) { 
    458                 wi_log_warn(WI_STR("message read failed")); 
    459                  
    460                 return false; 
    461         } 
     528        if(!p7_message) 
     529                return false; 
    462530 
    463531        if(!wi_is_equal(p7_message->name, WI_STR("p7.handshake.acknowledge"))) { 
    464                 wi_log_warn(WI_STR("wrong message (%@ != %@)"), p7_message->name, WI_STR("p7.handshake.acknowledge")); 
     532                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     533                        WI_STR("Message should be \"p7.handshake.acknowledge\", not \"%@\""), 
     534                        p7_message->name); 
    465535                 
    466536                return false; 
     
    482552        p7_message = wi_p7_socket_read_message(p7_socket, timeout); 
    483553         
    484         if(!p7_message) { 
    485                 wi_log_warn(WI_STR("couldn't read message")); 
    486  
    487                 return false; 
    488         } 
     554        if(!p7_message) 
     555                return false; 
    489556         
    490557        if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption"))) { 
    491                 wi_log_warn(WI_STR("wrong message")); 
     558                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     559                        WI_STR("Message should be \"p7.encryption\", not \"%@\""), 
     560                        p7_message->name); 
    492561                 
    493562                return false; 
     
    497566         
    498567        if(!rsa) { 
    499                 wi_log_warn(WI_STR("no certificate")); 
     568                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     569                        WI_STR("Message has no \"p7.encryption.envelope_key\" field")); 
    500570                 
    501571                return false; 
     
    504574        p7_socket->rsa = wi_rsa_init_with_public_key(wi_rsa_alloc(), rsa); 
    505575         
    506         if(!p7_socket->rsa) { 
    507                 wi_log_info(WI_STR("could not create rsa")); 
    508                  
    509                 return false; 
    510         } 
    511          
    512         p7_socket->cipher = wi_cipher_init_with_random_key(wi_cipher_alloc(), _wi_p7_socket_cipher(p7_socket)); 
    513          
    514         if(!p7_socket->cipher) { 
    515                 wi_log_info(WI_STR("could not create cipher")); 
    516  
    517                 return false; 
    518         } 
     576        if(!p7_socket->rsa) 
     577                return false; 
     578         
     579        p7_socket->cipher = wi_cipher_init_with_random_key(wi_cipher_alloc(), _WI_P7_ENCRYPTION_OPTIONS_TO_CIPHER(p7_socket->options)); 
     580         
     581        if(!p7_socket->cipher) 
     582                return false; 
    519583         
    520584        p7_message = wi_p7_message_with_name(WI_STR("p7.encryption.reply"), p7_socket); 
    521585 
    522         if(!p7_message) { 
    523                 wi_log_info(WI_STR("couldn't create message")); 
    524  
    525                 return false; 
    526         } 
     586        if(!p7_message) 
     587                return false; 
    527588         
    528589        data = wi_rsa_encrypt(p7_socket->rsa, wi_cipher_key(p7_socket->cipher)); 
    529590         
    530         wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.cipher_key")); 
     591        if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.cipher_key"))) 
     592                return false; 
    531593 
    532594        data = wi_cipher_iv(p7_socket->cipher); 
     
    534596        if(data) { 
    535597                data = wi_rsa_encrypt(p7_socket->rsa, data); 
    536                 wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.cipher_iv")); 
     598                 
     599                if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.cipher_iv"))) 
     600                        return false; 
    537601        } 
    538602         
    539603        data = wi_rsa_encrypt(p7_socket->rsa, wi_string_data(username)); 
    540604         
    541         if(!data) { 
    542                 wi_log_info(WI_STR("could not rsa encrypt")); 
    543                  
    544                 return false; 
    545         } 
    546          
    547         wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.username")); 
     605        if(!data) 
     606                return false; 
     607         
     608        if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.username"))) 
     609                return false; 
    548610         
    549611        if(!password) 
     
    555617        data = wi_rsa_encrypt(p7_socket->rsa, wi_string_data(client_password1)); 
    556618         
     619        if(!data) 
     620                return false; 
     621 
     622        if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.client_password"))) 
     623                return false; 
     624         
     625        if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) 
     626                return false; 
     627 
     628        p7_message = wi_p7_socket_read_message(p7_socket, timeout); 
     629         
     630        if(!p7_message) 
     631                return false; 
     632         
     633        if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption.acknowledge"))) { 
     634                wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, 
     635                        WI_STR("Message should be \"p7.encryption.acknowledge\", not \"%@\""), 
     636                        p7_message->name); 
     637                 
     638                return false; 
     639