Changeset 4376


Ignore:
Timestamp:
Feb 27, 2013 9:41:37 AM (11 years ago)
Author:
nanang
Message:

Re #1522: backported to 1.x

Location:
pjproject/branches/1.x
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/1.x

  • pjproject/branches/1.x/pjlib/include/pj/ssl_sock.h

    r3942 r4376  
    543543    pj_uint32_t         verify_status; 
    544544 
     545    /** 
     546     * Last native error returned by the backend. 
     547     */ 
     548    unsigned long       last_native_err; 
     549 
    545550} pj_ssl_sock_info; 
    546551 
  • pjproject/branches/1.x/pjlib/src/pj/ssl_sock_ossl.c

    r3942 r4376  
    159159    pj_status_t           verify_status; 
    160160 
     161    unsigned long         last_err; 
     162 
    161163    pj_sock_t             sock; 
    162164    pj_activesock_t      *asock; 
     
    213215#define PJ_SSL_ERRNO_SPACE_SIZE         PJ_ERRNO_SPACE_SIZE 
    214216 
    215 #define STATUS_FROM_SSL_ERR(err, status) { \ 
    216     status = ERR_GET_LIB(err)*300 + ERR_GET_REASON(err);\ 
    217     pj_assert(status < PJ_SSL_ERRNO_SPACE_SIZE);\ 
    218     if (status) status += PJ_SSL_ERRNO_START;\ 
    219 } 
    220  
    221 #define GET_SSL_STATUS(status) { \ 
    222     unsigned long e = ERR_get_error();\ 
    223     STATUS_FROM_SSL_ERR(e, status);\ 
    224 } 
     217/* Expected maximum value of reason component in OpenSSL error code */ 
     218#define MAX_OSSL_ERR_REASON             1200 
     219 
     220static pj_status_t STATUS_FROM_SSL_ERR(pj_ssl_sock_t *ssock, 
     221                                       unsigned long err) 
     222{ 
     223    pj_status_t status; 
     224 
     225    /* General SSL error, dig more from OpenSSL error queue */ 
     226    if (err == SSL_ERROR_SSL) 
     227        err = ERR_get_error(); 
     228 
     229    /* OpenSSL error range is much wider than PJLIB errno space, so 
     230     * if it exceeds the space, only the error reason will be kept. 
     231     * Note that the last native error will be kept as is and can be 
     232     * retrieved via SSL socket info. 
     233     */ 
     234    status = ERR_GET_LIB(err)*MAX_OSSL_ERR_REASON + ERR_GET_REASON(err); 
     235    if (status > PJ_SSL_ERRNO_SPACE_SIZE) 
     236        status = ERR_GET_REASON(err); 
     237 
     238    status += PJ_SSL_ERRNO_START; 
     239    ssock->last_err = err; 
     240    return status; 
     241} 
     242 
     243static pj_status_t GET_SSL_STATUS(pj_ssl_sock_t *ssock) 
     244{ 
     245    return STATUS_FROM_SSL_ERR(ssock, ERR_get_error()); 
     246} 
     247 
    225248 
    226249/* 
     
    236259        unsigned long l, r; 
    237260        ssl_err -= PJ_SSL_ERRNO_START; 
    238         l = ssl_err/300; 
    239         r = ssl_err%300; 
     261        l = ssl_err / MAX_OSSL_ERR_REASON; 
     262        r = ssl_err % MAX_OSSL_ERR_REASON; 
    240263        ssl_err = ERR_PACK(l, 0, r); 
    241264    } 
     
    245268    { 
    246269        const char *tmp = NULL; 
    247  
    248         if (ssl_err >= 300) 
    249             tmp = ERR_reason_error_string(ssl_err); 
    250         else 
    251             tmp = X509_verify_cert_error_string(ssl_err); 
    252  
     270        tmp = ERR_reason_error_string(ssl_err); 
    253271        if (tmp) { 
    254272            pj_ansi_strncpy(buf, tmp, bufsize); 
     
    518536    ctx = SSL_CTX_new(ssl_method); 
    519537    if (ctx == NULL) { 
    520         GET_SSL_STATUS(status); 
    521         return status; 
     538        return GET_SSL_STATUS(ssock); 
    522539    } 
    523540 
     
    530547 
    531548            if (rc != 1) { 
    532                 GET_SSL_STATUS(status); 
     549                status = GET_SSL_STATUS(ssock); 
    533550                PJ_LOG(1,(ssock->pool->obj_name, "Error loading CA list file " 
    534551                          "'%s'", cert->CA_file.ptr)); 
     
    552569 
    553570            if(rc != 1) { 
    554                 GET_SSL_STATUS(status); 
     571                status = GET_SSL_STATUS(ssock); 
    555572                PJ_LOG(1,(ssock->pool->obj_name, "Error loading certificate " 
    556573                          "chain file '%s'", cert->cert_file.ptr)); 
     
    568585 
    569586            if(rc != 1) { 
    570                 GET_SSL_STATUS(status); 
     587                status = GET_SSL_STATUS(ssock); 
    571588                PJ_LOG(1,(ssock->pool->obj_name, "Error adding private key " 
    572589                          "from '%s'", cert->privkey_file.ptr)); 
     
    581598    ssock->ossl_ssl = SSL_new(ssock->ossl_ctx); 
    582599    if (ssock->ossl_ssl == NULL) { 
    583         GET_SSL_STATUS(status); 
    584         return status; 
     600        return GET_SSL_STATUS(ssock); 
    585601    } 
    586602 
     
    714730    ret = SSL_set_cipher_list(ssock->ossl_ssl, buf); 
    715731    if (ret < 1) { 
    716         pj_status_t status; 
    717         GET_SSL_STATUS(status); 
    718         return status; 
     732        return GET_SSL_STATUS(ssock); 
    719733    } 
    720734 
     
    10211035         */ 
    10221036        if (status != PJ_SUCCESS) { 
     1037            /* Server disconnected us, possibly due to SSL nego failure */ 
     1038            if (status == PJ_EEOF) { 
     1039                unsigned long err; 
     1040                err = ERR_get_error(); 
     1041                if (err != SSL_ERROR_NONE) 
     1042                    status = STATUS_FROM_SSL_ERR(ssock, err); 
     1043            } 
    10231044            reset_ssl_sock_state(ssock); 
    10241045        } 
     
    11971218    /* Perform SSL handshake */ 
    11981219    err = SSL_do_handshake(ssock->ossl_ssl); 
    1199     if (err < 0) { 
    1200         err = SSL_get_error(ssock->ossl_ssl, err); 
    1201         if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ)  
    1202         { 
    1203             /* Handshake fails */ 
    1204             GET_SSL_STATUS(status); 
    1205             pj_lock_release(ssock->write_mutex); 
    1206             return status; 
    1207         } 
    1208     } 
    12091220 
    12101221    /* SSL_do_handshake() may put some pending data into SSL write BIO,  
     
    12191230    pj_lock_release(ssock->write_mutex); 
    12201231 
     1232    if (err < 0) { 
     1233        err = SSL_get_error(ssock->ossl_ssl, err); 
     1234        if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ)  
     1235        { 
     1236            /* Handshake fails */ 
     1237            status = STATUS_FROM_SSL_ERR(ssock, err); 
     1238            return status; 
     1239        } 
     1240    } 
     1241 
    12211242    /* Check if handshake has been completed */ 
    12221243    if (SSL_is_init_finished(ssock->ossl_ssl)) { 
     
    12501271        nwritten = BIO_write(ssock->ossl_rbio, data, size); 
    12511272        if (nwritten < size) { 
    1252             GET_SSL_STATUS(status); 
     1273            status = GET_SSL_STATUS(ssock); 
    12531274            goto on_error; 
    12541275        } 
     
    13241345                { 
    13251346                    /* Reset SSL socket state, then return PJ_FALSE */ 
    1326                     GET_SSL_STATUS(status); 
     1347                    status = STATUS_FROM_SSL_ERR(ssock, err); 
    13271348                    reset_ssl_sock_state(ssock); 
    13281349                    goto on_error; 
     
    19051926        info->verify_status = ssock->verify_status; 
    19061927    } 
     1928 
     1929    /* Last known OpenSSL error code */ 
     1930    info->last_native_err = ssock->last_err; 
    19071931 
    19081932    return PJ_SUCCESS; 
     
    20522076        } else { 
    20532077            /* Some problem occured */ 
    2054             GET_SSL_STATUS(status); 
     2078            status = STATUS_FROM_SSL_ERR(ssock, err); 
    20552079        } 
    20562080    } else { 
     
    23792403    ret = SSL_renegotiate(ssock->ossl_ssl); 
    23802404    if (ret <= 0) { 
    2381         GET_SSL_STATUS(status); 
     2405        status = GET_SSL_STATUS(ssock); 
    23822406    } else { 
    23832407        status = do_handshake(ssock); 
  • pjproject/branches/1.x/pjsip/src/pjsip/sip_transport_tls.c

    r3942 r4376  
    195195    if (state_cb) { 
    196196        pjsip_transport_state_info state_info; 
    197  
     197        pjsip_tls_state_info tls_info; 
     198        pj_ssl_sock_info ssl_info; 
     199         
     200        /* Init transport state info */ 
    198201        pj_bzero(&state_info, sizeof(state_info)); 
    199202        state_info.status = tls->close_reason; 
     203 
     204        if (tls->ssock &&  
     205            pj_ssl_sock_get_info(tls->ssock, &ssl_info) == PJ_SUCCESS) 
     206        { 
     207            pj_bzero(&tls_info, sizeof(tls_info)); 
     208            tls_info.ssl_sock_info = &ssl_info; 
     209            state_info.ext_info = &tls_info; 
     210        } 
     211 
    200212        (*state_cb)(&tls->base, PJSIP_TP_STATE_DISCONNECTED, &state_info); 
    201213    } 
Note: See TracChangeset for help on using the changeset viewer.