JSS_throwMsg(env, SOCKET_EXCEPTION,
JSS_throwMsgPrErr(env, SOCKET_EXCEPTION,
Java_org_mozilla_jss_ssl_SSLSocket_getStatus    (JNIEnv *env, jobject self){    SECStatus secstatus;    JSSL_SocketData *sock=NULL;    int on;    char *cipher=NULL;    jobject cipherString;    jint keySize;    jint secretKeySize;    char *issuer=NULL;    jobject issuerString;    char *subject=NULL;    jobject subjectString;    jobject statusObj = NULL;    jclass statusClass;    jmethodID statusCons;    CERTCertificate *peerCert=NULL;    jobject peerCertObj = NULL;    char *serialNum = NULL;    jobject serialNumObj = NULL;    /* get the fd */    if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) {        /* exception was thrown */        goto finish;    }    /* get the status */    secstatus = SSL_SecurityStatus( sock->fd,                                    &on,                                    &cipher,                                    (int*)&keySize,                                    (int*)&secretKeySize,                                    &issuer,                                    &subject);    if(secstatus != SECSuccess) {        JSS_throwMsg(env, SOCKET_EXCEPTION,            "Failed to retrieve socket security status");        goto finish;    }    /*     * get the peer certificate     */    peerCert = SSL_PeerCertificate(sock->fd);    if( peerCert != NULL ) {        /* the peer cert might be null, for example if this is the server         * side and the client didn't auth. */        serialNum = CERT_Hexify(&peerCert->serialNumber, PR_FALSE /*do_colon*/);        PR_ASSERT(serialNum != NULL);        serialNumObj = (*env)->NewStringUTF(env, serialNum);        if( serialNumObj == NULL ) {            goto finish;        }        /* this call will wipe out peerCert */        peerCertObj = JSS_PK11_wrapCert(env, &peerCert);        if( peerCertObj == NULL) {            goto finish;        }    }    /*     * convert char*s to Java Strings     */    cipherString = issuerString = subjectString = NULL;    if( cipher != NULL ) cipherString = (*env)->NewStringUTF(env, cipher);    if( issuer != NULL ) issuerString = (*env)->NewStringUTF(env, issuer);    if( subject != NULL ) subjectString = (*env)->NewStringUTF(env, subject);    /*     * package the status into a new SSLSecurityStatus object     */    statusClass = (*env)->FindClass(env, SSL_SECURITY_STATUS_CLASS_NAME);    PR_ASSERT(statusClass != NULL);    if( statusClass == NULL ) {        /* exception was thrown */        goto finish;    }    statusCons = (*env)->GetMethodID(env, statusClass,                            SSL_SECURITY_STATUS_CONSTRUCTOR_NAME,                            SSL_SECURITY_STATUS_CONSTRUCTOR_SIG);    PR_ASSERT(statusCons != NULL);    if(statusCons == NULL ) {        /* exception was thrown */        goto finish;    }    statusObj = (*env)->NewObject(env, statusClass, statusCons,            on, cipherString, keySize, secretKeySize, issuerString,            subjectString, serialNumObj, peerCertObj);        finish:    if( cipher != NULL ) {        PR_Free(cipher);    }    if( issuer != NULL ) {        PR_Free(issuer);    }    /* subject is not allocated so it doesn't need to be freed */    if( peerCert != NULL ) {        CERT_DestroyCertificate(peerCert);    }    if( serialNum != NULL ) {        PR_Free(serialNum);    }    return statusObj;}