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); }
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; }
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); } } }
/** 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; }
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; }
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); }