Changeset 5518


Ignore:
Timestamp:
Jan 11, 2017 1:41:31 AM (3 years ago)
Author:
ming
Message:

Fixed #1960: Export SIP transport TLS state and TLS certificate info to PJSUA2

Location:
pjproject/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/swig/symbols.i

    r5493 r5518  
    3434 
    3535typedef enum pj_ssl_sock_proto {PJ_SSL_SOCK_PROTO_DEFAULT = 0, PJ_SSL_SOCK_PROTO_SSL2 = 1 << 0, PJ_SSL_SOCK_PROTO_SSL3 = 1 << 1, PJ_SSL_SOCK_PROTO_TLS1 = 1 << 2, PJ_SSL_SOCK_PROTO_TLS1_1 = 1 << 3, PJ_SSL_SOCK_PROTO_TLS1_2 = 1 << 4, PJ_SSL_SOCK_PROTO_SSL23 = (1 << 16) - 1, PJ_SSL_SOCK_PROTO_DTLS1 = 1 << 16} pj_ssl_sock_proto; 
     36 
     37typedef enum pj_ssl_cert_name_type {PJ_SSL_CERT_NAME_UNKNOWN = 0, PJ_SSL_CERT_NAME_RFC822, PJ_SSL_CERT_NAME_DNS, PJ_SSL_CERT_NAME_URI, PJ_SSL_CERT_NAME_IP} pj_ssl_cert_name_type; 
     38 
     39typedef enum pj_ssl_cert_verify_flag_t {PJ_SSL_CERT_ESUCCESS = 0, PJ_SSL_CERT_EISSUER_NOT_FOUND = (1 << 0), PJ_SSL_CERT_EUNTRUSTED = (1 << 1), PJ_SSL_CERT_EVALIDITY_PERIOD = (1 << 2), PJ_SSL_CERT_EINVALID_FORMAT = (1 << 3), PJ_SSL_CERT_EINVALID_PURPOSE = (1 << 4), PJ_SSL_CERT_EISSUER_MISMATCH = (1 << 5), PJ_SSL_CERT_ECRL_FAILURE = (1 << 6), PJ_SSL_CERT_EREVOKED = (1 << 7), PJ_SSL_CERT_ECHAIN_TOO_LONG = (1 << 8), PJ_SSL_CERT_EIDENTITY_NOT_MATCH = (1 << 30), PJ_SSL_CERT_EUNKNOWN = (1 << 31)} pj_ssl_cert_verify_flag_t; 
    3640 
    3741typedef enum pj_stun_nat_type {PJ_STUN_NAT_TYPE_UNKNOWN, PJ_STUN_NAT_TYPE_ERR_UNKNOWN, PJ_STUN_NAT_TYPE_OPEN, PJ_STUN_NAT_TYPE_BLOCKED, PJ_STUN_NAT_TYPE_SYMMETRIC_UDP, PJ_STUN_NAT_TYPE_FULL_CONE, PJ_STUN_NAT_TYPE_SYMMETRIC, PJ_STUN_NAT_TYPE_RESTRICTED, PJ_STUN_NAT_TYPE_PORT_RESTRICTED} pj_stun_nat_type; 
  • pjproject/trunk/pjsip-apps/src/swig/symbols.lst

    r5417 r5518  
    33pj/log.h                        pj_log_decoration 
    44pj/sock_qos.h                   pj_qos_type pj_qos_flag pj_qos_wmm_prio pj_qos_params 
    5 pj/ssl_sock.h                   pj_ssl_cipher pj_ssl_sock_proto 
     5pj/ssl_sock.h                   pj_ssl_cipher pj_ssl_sock_proto pj_ssl_cert_name_type pj_ssl_cert_verify_flag_t 
    66 
    77pjnath/nat_detect.h             pj_stun_nat_type 
  • pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp

    r5417 r5518  
    125125 
    126126/** 
     127 * SSL certificate type and name structure. 
     128 */ 
     129struct SslCertName 
     130{ 
     131    pj_ssl_cert_name_type  type;            /**< Name type              */ 
     132    string                 name;            /**< The name               */ 
     133}; 
     134 
     135/** 
     136 * SSL certificate information. 
     137 */ 
     138struct SslCertInfo 
     139{ 
     140    unsigned            version;            /**< Certificate version    */ 
     141    unsigned char       serialNo[20];       /**< Serial number, array 
     142                                                 of octets, first index 
     143                                                 is MSB                 */ 
     144    string              subjectCn;          /**< Subject common name    */ 
     145    string              subjectInfo;        /**< One line subject, fields 
     146                                                 are separated by slash, e.g: 
     147                                                 "CN=sample.org/OU=HRD" */ 
     148 
     149    string              issuerCn;           /**< Issuer common name     */ 
     150    string              issuerInfo;         /**< One line subject, fields 
     151                                                 are separated by slash */ 
     152 
     153    TimeVal             validityStart;      /**< Validity start         */ 
     154    TimeVal             validityEnd;        /**< Validity end           */ 
     155    bool                validityGmt;        /**< Flag if validity  
     156                                                 date/time use GMT      */ 
     157 
     158    vector<SslCertName> subjectAltName;     /**< Subject alternative 
     159                                                 name extension         */ 
     160 
     161    string              raw;                /**< Raw certificate in PEM 
     162                                                 format, only available 
     163                                                 for remote certificate */ 
     164 
     165public: 
     166    /** 
     167     * Check if the info is set with empty values. 
     168     * 
     169     * @return          True if the info is empty. 
     170     */ 
     171    bool isEmpty() const; 
     172 
     173    /** 
     174     * Convert from pjsip 
     175     */ 
     176    void fromPj(const pj_ssl_cert_info &info); 
     177}; 
     178 
     179/** 
     180 * TLS transport information. 
     181 */ 
     182struct TlsInfo 
     183{ 
     184    /** 
     185     * Describes whether secure socket connection is established, i.e: TLS/SSL  
     186     * handshaking has been done successfully. 
     187     */ 
     188    bool                established; 
     189 
     190    /** 
     191     * Describes secure socket protocol being used, see #pj_ssl_sock_proto.  
     192     * Use bitwise OR operation to combine the protocol type. 
     193     */ 
     194    unsigned            protocol; 
     195 
     196    /** 
     197     * Describes cipher suite being used, this will only be set when connection 
     198     * is established. 
     199     */ 
     200    pj_ssl_cipher       cipher; 
     201 
     202    /** 
     203     * Describes cipher name being used, this will only be set when connection 
     204     * is established. 
     205     */ 
     206    string              cipherName; 
     207 
     208    /** 
     209     * Describes local address. 
     210     */ 
     211    SocketAddress       localAddr; 
     212 
     213    /** 
     214     * Describes remote address. 
     215     */ 
     216    SocketAddress       remoteAddr; 
     217    
     218    /** 
     219     * Describes active local certificate info. Use SslCertInfo.isEmpty() 
     220     * to check if the local cert info is available. 
     221     */ 
     222    SslCertInfo         localCertInfo; 
     223    
     224    /** 
     225     * Describes active remote certificate info. Use SslCertInfo.isEmpty() 
     226     * to check if the remote cert info is available. 
     227     */ 
     228    SslCertInfo         remoteCertInfo; 
     229 
     230    /** 
     231     * Status of peer certificate verification. 
     232     */ 
     233    unsigned            verifyStatus; 
     234 
     235    /** 
     236     * Error messages (if any) of peer certificate verification, based on 
     237     * the field verifyStatus above. 
     238     */ 
     239    StringVector        verifyMsgs; 
     240 
     241public: 
     242    /** 
     243     * Constructor. 
     244     */ 
     245    TlsInfo(); 
     246 
     247    /** 
     248     * Check if the info is set with empty values. 
     249     * 
     250     * @return          True if the info is empty. 
     251     */ 
     252    bool isEmpty() const; 
     253 
     254    /** 
     255     * Convert from pjsip 
     256     */ 
     257    void fromPj(const pjsip_tls_state_info &info); 
     258}; 
     259 
     260/** 
    127261 * Parameter of Endpoint::onTransportState() callback. 
    128262 */ 
     
    133267     */ 
    134268    TransportHandle     hnd; 
     269     
     270    /** 
     271     * The transport type. 
     272     */ 
     273    string              type; 
    135274 
    136275    /** 
     
    143282     */ 
    144283    pj_status_t         lastError; 
     284     
     285    /** 
     286     * TLS transport info, only used if transport type is TLS. Use  
     287     * TlsInfo.isEmpty() to check if this info is available. 
     288     */ 
     289    TlsInfo             tlsInfo; 
    145290}; 
    146291 
     
    10301175     */ 
    10311176    void transportClose(TransportId id) throw(Error); 
     1177     
     1178    /** 
     1179     * Start graceful shutdown procedure for this transport handle. After 
     1180     * graceful shutdown has been initiated, no new reference can be 
     1181     * obtained for the transport. However, existing objects that currently 
     1182     * uses the transport may still use this transport to send and receive 
     1183     * packets. After all objects release their reference to this transport, 
     1184     * the transport will be destroyed immediately. 
     1185     * 
     1186     * Note: application normally uses this API after obtaining the handle 
     1187     * from onTransportState() callback. 
     1188     * 
     1189     * @param tp                The transport. 
     1190     */ 
     1191    void transportShutdown(TransportHandle tp) throw(Error); 
    10321192 
    10331193    /************************************************************************* 
  • pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp

    r5501 r5518  
    4545/////////////////////////////////////////////////////////////////////////////// 
    4646 
     47TlsInfo::TlsInfo() 
     48{ 
     49    pj_bzero(this, sizeof(TlsInfo)); 
     50} 
     51 
     52bool TlsInfo::isEmpty() const 
     53{ 
     54    TlsInfo dummy; 
     55 
     56    pj_bzero(&dummy, sizeof(dummy)); 
     57    return ((pj_memcmp(this, &dummy, sizeof(dummy)) == 0)? true: false); 
     58} 
     59 
     60void TlsInfo::fromPj(const pjsip_tls_state_info &info) 
     61{ 
     62#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0 
     63    pj_ssl_sock_info *ssock_info = info.ssl_sock_info; 
     64    char straddr[PJ_INET6_ADDRSTRLEN+10]; 
     65    const char *verif_msgs[32]; 
     66    unsigned verif_msg_cnt; 
     67     
     68    established = PJ2BOOL(ssock_info->established); 
     69    protocol    = ssock_info->proto; 
     70    cipher      = ssock_info->cipher; 
     71    cipherName  = pj_ssl_cipher_name(ssock_info->cipher); 
     72    pj_sockaddr_print(&ssock_info->local_addr, straddr, sizeof(straddr), 3); 
     73    localAddr   = straddr; 
     74    pj_sockaddr_print(&ssock_info->remote_addr, straddr, sizeof(straddr),3); 
     75    remoteAddr  = straddr; 
     76    verifyStatus = ssock_info->verify_status; 
     77    if (ssock_info->local_cert_info) 
     78        localCertInfo.fromPj(*ssock_info->local_cert_info); 
     79    if (ssock_info->remote_cert_info) 
     80        remoteCertInfo.fromPj(*ssock_info->remote_cert_info); 
     81     
     82    /* Dump server TLS certificate verification result */ 
     83    verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs); 
     84    pj_ssl_cert_get_verify_status_strings(ssock_info->verify_status, 
     85                                          verif_msgs, &verif_msg_cnt); 
     86    for (unsigned i = 0; i < verif_msg_cnt; ++i) { 
     87        verifyMsgs.push_back(verif_msgs[i]); 
     88    } 
     89#endif 
     90} 
     91 
     92bool SslCertInfo::isEmpty() const 
     93{ 
     94    SslCertInfo dummy; 
     95 
     96    pj_bzero(&dummy, sizeof(dummy)); 
     97    return ((pj_memcmp(this, &dummy, sizeof(dummy)) == 0)? true: false); 
     98} 
     99 
     100void SslCertInfo::fromPj(const pj_ssl_cert_info &info) 
     101{ 
     102    version     = info.version; 
     103    pj_memcpy(serialNo, info.serial_no, sizeof(info.serial_no)); 
     104    subjectCn   = pj2Str(info.subject.cn); 
     105    subjectInfo = pj2Str(info.subject.info); 
     106    issuerCn    = pj2Str(info.issuer.cn); 
     107    issuerInfo  = pj2Str(info.issuer.info); 
     108    validityStart.fromPj(info.validity.start); 
     109    validityEnd.fromPj(info.validity.end); 
     110    validityGmt = PJ2BOOL(info.validity.gmt); 
     111    raw         = pj2Str(info.raw); 
     112 
     113    for (unsigned i = 0; i < info.subj_alt_name.cnt; i++) { 
     114        SslCertName cname; 
     115        cname.type = info.subj_alt_name.entry[i].type; 
     116        cname.name = pj2Str(info.subj_alt_name.entry[i].name); 
     117        subjectAltName.push_back(cname); 
     118    } 
     119} 
     120 
     121/////////////////////////////////////////////////////////////////////////////// 
     122 
    47123UaConfig::UaConfig() 
    48124: mainThreadOnly(false) 
     
    559635 
    560636    prm.hnd = (TransportHandle)tp; 
     637    prm.type = tp->type_name; 
    561638    prm.state = state; 
    562639    prm.lastError = info ? info->status : PJ_SUCCESS; 
     640    pj_bzero(&prm.tlsInfo, sizeof(TlsInfo)); 
     641 
     642#if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0 
     643    if (!pj_ansi_stricmp(tp->type_name, "tls") && info->ext_info && 
     644        (state == PJSIP_TP_STATE_CONNECTED ||  
     645         ((pjsip_tls_state_info*)info->ext_info)-> 
     646                                 ssl_sock_info->verify_status != PJ_SUCCESS)) 
     647    { 
     648        prm.tlsInfo.fromPj(*((pjsip_tls_state_info*)info->ext_info)); 
     649    } 
     650#endif 
    563651 
    564652    ep.onTransportState(prm); 
     
    16951783} 
    16961784 
     1785void Endpoint::transportShutdown(TransportHandle tp) throw(Error) 
     1786{ 
     1787    PJSUA2_CHECK_EXPR( pjsip_transport_shutdown((pjsip_transport *)tp) ); 
     1788} 
     1789 
    16971790/////////////////////////////////////////////////////////////////////////////// 
    16981791/* 
Note: See TracChangeset for help on using the changeset viewer.