Esempio n. 1
0
void 
printSecurityInfo(FILE *outfile, PRFileDesc *fd)
{
    char * cp;	/* bulk cipher name */
    char * ip;	/* cert issuer DN */
    char * sp;	/* cert subject DN */
    int    op;	/* High, Low, Off */
    int    kp0;	/* total key bits */
    int    kp1;	/* secret key bits */
    int    result;
    SSL3Statistics * ssl3stats = SSL_GetStatistics();

    if (!outfile) {
	outfile = stdout;
    }

    result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
    if (result != SECSuccess)
	return;
    fprintf(outfile,
     "   bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
     "   subject DN:\n %s\n"
     "   issuer  DN:\n %s\n", cp, kp1, kp0, op, sp, ip);
    PR_Free(cp);
    PR_Free(ip);
    PR_Free(sp);

    fprintf(outfile,
      "   %ld cache hits; %ld cache misses, %ld cache not reusable\n",
	    ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses,
    ssl3stats->hch_sid_cache_not_ok);

}
Esempio n. 2
0
enum okay
ssl_open(const char *server, struct sock *sp, const char *uhp)
{
	PRFileDesc	*fdp, *fdc;

	if (nss_init() == STOP)
		return STOP;
	ssl_set_vrfy_level(uhp);
	nss_select_method(uhp);
	if ((fdp = PR_ImportTCPSocket(sp->s_fd)) == NULL) {
		nss_gen_err("Error importing OS file descriptor");
		return STOP;
	}
	if ((fdc = SSL_ImportFD(NULL, fdp)) == NULL) {
		nss_gen_err("Error importing NSPR file descriptor");
		PR_Close(fdp);
		return STOP;
	}
	SSL_SetURL(fdc, server);
	SSL_SetPKCS11PinArg(fdc, NULL);
	SSL_BadCertHook(fdc, bad_cert_cb, NULL);
	if (SSL_ResetHandshake(fdc, PR_FALSE) != SECSuccess) {
		nss_gen_err("Cannot reset NSS handshake");
		PR_Close(fdc);
		return STOP;
	}
	if (SSL_ForceHandshake(fdc) != 0) {
		nss_gen_err("SSL/TLS handshake failed");
		PR_Close(fdc);
		return STOP;
	}
	sp->s_prfd = fdc;
	if (nss_check_host(server, sp) != OKAY && ssl_vrfy_decide() != OKAY) {
		PR_Close(fdc);
		sp->s_prfd = NULL;
		return STOP;
	}
	sp->s_use_ssl = 1;
	if (verbose) {
		char	*cipher, *issuer, *subject;
		int	keysize, secretkeysize;

		if (SSL_SecurityStatus(fdc, NULL, &cipher,
					&keysize, &secretkeysize,
					&issuer, &subject) == SECSuccess) {
			fprintf(stderr, "SSL parameters: cipher=%s, "
					"keysize=%d, secretkeysize=%d,\n"
					"issuer=%s\n"
					"subject=%s\n",
					cipher, keysize, secretkeysize,
					issuer, subject);
			PR_Free(cipher);
			PR_Free(issuer);
			PR_Free(subject);
		} else
			nss_gen_err("Could not read status information");
	}
	return OKAY;
}
Esempio n. 3
0
static int
__pmSecureServerNegotiation(int fd, int *strength)
{
    PRIntervalTime timer;
    PRFileDesc *sslsocket;
    SECStatus secsts;
    int enabled, keysize;
    int msec;

    sslsocket = (PRFileDesc *)__pmGetSecureSocket(fd);
    if (!sslsocket)
	return PM_ERR_IPC;

    PM_INIT_LOCKS();
    PM_LOCK(secureserver_lock);
    secsts = SSL_ConfigSecureServer(sslsocket,
			secure_server.certificate,
			secure_server.private_key,
			secure_server.certificate_KEA);
    PM_UNLOCK(secureserver_lock);

    if (secsts != SECSuccess) {
	pmNotifyErr(LOG_ERR, "Unable to configure secure server: %s",
			    pmErrStr(__pmSecureSocketsError(PR_GetError())));
	return PM_ERR_IPC;
    }

    secsts = SSL_ResetHandshake(sslsocket, PR_TRUE /*server*/);
    if (secsts != SECSuccess) {
	pmNotifyErr(LOG_ERR, "Unable to reset secure handshake: %s",
			    pmErrStr(__pmSecureSocketsError(PR_GetError())));
	return PM_ERR_IPC;
    }

    /* Server initiates handshake now to get early visibility of errors */
    msec = __pmConvertTimeout(TIMEOUT_DEFAULT);
    timer = PR_MillisecondsToInterval(msec);
    secsts = SSL_ForceHandshakeWithTimeout(sslsocket, timer);
    if (secsts != SECSuccess) {
	pmNotifyErr(LOG_ERR, "Unable to force secure handshake: %s",
			    pmErrStr(__pmSecureSocketsError(PR_GetError())));
	return PM_ERR_IPC;
    }

    secsts = SSL_SecurityStatus(sslsocket, &enabled, NULL, &keysize, NULL, NULL, NULL);
    if (secsts != SECSuccess)
	return __pmSecureSocketsError(PR_GetError());

    *strength = (enabled > 0) ? keysize : DEFAULT_SECURITY_STRENGTH;
    return 0;
}
NSAPI_PUBLIC void INTsession_fill_ssl(Session *sn)
{
    PRInt32 secon = -1;
    PRInt32 keySize, secretKeySize;
    char *cipher;
    char *issuer_dn;
    char *user_dn;
    char *idstr;
    SECItem *iditem;

    // we'll call SSL_SecurityStatus both when we know that SSL is on
    // or when we don't know anything.
    // either way, we can do this only when we have a descriptor.
    // if we don't have one, we're in a VSInit.
    if (sn->ssl && sn->csd_open) {
        if (!SSL_SecurityStatus(sn->csd, &secon, &cipher, &keySize,
                                &secretKeySize, &issuer_dn, &user_dn)) {
            if(secon > 0) {
                sn->ssl = 1;

                int cipher_len = cipher ? strlen(cipher) : 0;
                int issuer_dn_len = issuer_dn ? strlen(issuer_dn) : 0;
                int user_dn_len = user_dn ? strlen(user_dn) : 0;
                pblock_kvinsert(pb_key_cipher, cipher, cipher_len, sn->client);
                pblock_kninsert(pb_key_keysize, keySize, sn->client);
                pblock_kninsert(pb_key_secret_keysize, secretKeySize, sn->client);
                pblock_kvinsert(pb_key_issuer_dn, issuer_dn, issuer_dn_len, sn->client);
                pblock_kvinsert(pb_key_user_dn, user_dn, user_dn_len, sn->client);

                iditem = SSL_GetSessionID(sn->csd);
                if (iditem) {
                    /* Convert to base64 ASCII encoding */
                    idstr = BTOA_DataToAscii(iditem->data, iditem->len);
                    if (idstr) {
                        /* Add encoding to client pblock */
                        pblock_kvinsert(pb_key_ssl_id, idstr, strlen(idstr), sn->client);
                    }

                    /* Free the encoding buffer (pblock_nvinsert dups it) */
                    SECITEM_FreeItem(iditem, PR_TRUE);
                    PR_Free(idstr);
                }
            }
            if (cipher) PORT_Free (cipher);
            if (issuer_dn) PORT_Free (issuer_dn);
            if (user_dn) PORT_Free (user_dn);
        }
    }
}
Esempio n. 5
0
/** get the bit length of the current cipher's key */
int SslSocket::getKeyLen() const
{
    int enabled = 0;
    int keySize = 0;
    SECStatus   rc;

    rc = SSL_SecurityStatus( nssSocket,
                             &enabled,
                             NULL,
                             NULL,
                             &keySize,
                             NULL, NULL );
    if (rc == SECSuccess && enabled) {
        return keySize;
    }
    return 0;
}
Esempio n. 6
0
JNIEXPORT jobject JNICALL
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) {
        JSSL_throwSSLSocketException(env,
            "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 ) {
        PORT_Free(issuer);
    }
    if ( subject != NULL) {
        PORT_Free(subject);
    }
    if( peerCert != NULL ) {
        CERT_DestroyCertificate(peerCert);
    }
    if( serialNum != NULL ) {
        PR_Free(serialNum);
    }

    EXCEPTION_CHECK(env, sock)
    return statusObj;
}
Esempio n. 7
0
void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) {
  nsNSSShutDownPreventionLock locker;
  PRInt32 sslStatus;
  char* signer = nsnull;
  char* cipherName = nsnull;
  PRInt32 keyLength;
  nsresult rv;
  PRInt32 encryptBits;

  if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength,
                                       &encryptBits, &signer, nsnull)) {
    return;
  }

  PRInt32 secStatus;
  if (sslStatus == SSL_SECURITY_STATUS_OFF)
    secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
  else if (encryptBits >= 90)
    secStatus = (nsIWebProgressListener::STATE_IS_SECURE |
                 nsIWebProgressListener::STATE_SECURE_HIGH);
  else
    secStatus = (nsIWebProgressListener::STATE_IS_SECURE |
                 nsIWebProgressListener::STATE_SECURE_LOW);

  CERTCertificate *peerCert = SSL_PeerCertificate(fd);
  const char* caName = nsnull; // caName is a pointer only, no ownership
  char* certOrgName = CERT_GetOrgName(&peerCert->issuer);
  CERT_DestroyCertificate(peerCert);
  caName = certOrgName ? certOrgName : signer;

  const char* verisignName = "Verisign, Inc.";
  // If the CA name is RSA Data Security, then change the name to the real
  // name of the company i.e. VeriSign, Inc.
  if (nsCRT::strcmp((const char*)caName, "RSA Data Security, Inc.") == 0) {
    caName = verisignName;
  }

  nsAutoString shortDesc;
  const PRUnichar* formatStrings[1] = { ToNewUnicode(NS_ConvertUTF8toUTF16(caName)) };
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_SUCCEEDED(rv)) {
    rv = nssComponent->PIPBundleFormatStringFromName("SignedBy",
                                                   formatStrings, 1,
                                                   shortDesc);

    nsMemory::Free(const_cast<PRUnichar*>(formatStrings[0]));

    nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
    infoObject->SetSecurityState(secStatus);
    infoObject->SetShortSecurityDescription(shortDesc.get());

    /* Set the SSL Status information */
    nsRefPtr<nsSSLStatus> status = infoObject->SSLStatus();
    if (!status) {
      status = new nsSSLStatus();
      infoObject->SetSSLStatus(status);
    }

    CERTCertificate *serverCert = SSL_PeerCertificate(fd);
    if (serverCert) {
      nsRefPtr<nsNSSCertificate> nssc = new nsNSSCertificate(serverCert);
      CERT_DestroyCertificate(serverCert);
      serverCert = nsnull;

      nsCOMPtr<nsIX509Cert> prevcert;
      infoObject->GetPreviousCert(getter_AddRefs(prevcert));

      PRBool equals_previous = PR_FALSE;
      if (prevcert) {
        nsresult rv = nssc->Equals(prevcert, &equals_previous);
        if (NS_FAILED(rv)) {
          equals_previous = PR_FALSE;
        }
      }

      if (equals_previous) {
        PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
               ("HandshakeCallback using PREV cert %p\n", prevcert.get()));
        infoObject->SetCert(prevcert);
        status->mServerCert = prevcert;
      }
      else {
        if (status->mServerCert) {
          PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
                 ("HandshakeCallback KEEPING cert %p\n", status->mServerCert.get()));
          infoObject->SetCert(status->mServerCert);
        }
        else {
          PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
                 ("HandshakeCallback using NEW cert %p\n", nssc.get()));
          infoObject->SetCert(nssc);
          status->mServerCert = nssc;
        }
      }
    }

    status->mHaveKeyLengthAndCipher = PR_TRUE;
    status->mKeyLength = keyLength;
    status->mSecretKeyLength = encryptBits;
    status->mCipherName.Adopt(cipherName);
  }

  PR_FREEIF(certOrgName);
  PR_Free(signer);
}