Back to index

lightning-sunbird  0.9+nobinonly
Functions | Variables
sslsample.c File Reference
#include "sslsample.h"
#include "sslerror.h"

Go to the source code of this file.

Functions

char * myPasswd (PK11SlotInfo *info, PRBool retry, void *arg)
SECStatus myAuthCertificate (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isServer)
SECStatus myBadCertHandler (void *arg, PRFileDesc *socket)
SECStatus myGetClientAuthData (void *arg, PRFileDesc *socket, struct CERTDistNamesStr *caNames, struct CERTCertificateStr **pRetCert, struct SECKEYPrivateKeyStr **pRetKey)
SECStatus myHandshakeCallback (PRFileDesc *socket, void *arg)
void disableAllSSLCiphers (void)
void errWarn (char *function)
void exitErr (char *function)
void printSecurityInfo (PRFileDesc *fd)
void thread_wrapper (void *arg)
SECStatus launch_thread (GlobalThreadMgr *threadMGR, startFn *startFunc, void *a, int b)
SECStatus reap_threads (GlobalThreadMgr *threadMGR)
void destroy_thread_data (GlobalThreadMgr *threadMGR)
void lockedVars_Init (lockedVars *lv)
void lockedVars_Destroy (lockedVars *lv)
void lockedVars_WaitForDone (lockedVars *lv)
int lockedVars_AddToCount (lockedVars *lv, int addend)

Variables

int ssl2CipherSuites []
int ssl3CipherSuites []

Function Documentation

Definition at line 531 of file sslsample.c.

{
       PORT_Memset(threadMGR->threads, 0, sizeof(threadMGR->threads));

       if (threadMGR->threadEndQ) {
              PR_DestroyCondVar(threadMGR->threadEndQ);
              threadMGR->threadEndQ = NULL;
       }
       if (threadMGR->threadStartQ) {
              PR_DestroyCondVar(threadMGR->threadStartQ);
              threadMGR->threadStartQ = NULL;
       }
       if (threadMGR->threadLock) {
              PR_DestroyLock(threadMGR->threadLock);
              threadMGR->threadLock = NULL;
       }
}

Here is the call graph for this function:

Definition at line 329 of file sslsample.c.

{
    const PRUint16 *cipherSuites = SSL_ImplementedCiphers;
    int             i            = SSL_NumImplementedCiphers;
    SECStatus       rv;

    /* disable all the SSL3 cipher suites */
    while (--i >= 0) {
       PRUint16 suite = cipherSuites[i];
        rv = SSL_CipherPrefSetDefault(suite, PR_FALSE);
       if (rv != SECSuccess) {
           printf("SSL_CipherPrefSetDefault didn't like value 0x%04x (i = %d)\n",
                 suite, i);
           errWarn("SSL_CipherPrefSetDefault");
           exit(2);
       }
    }
}

Here is the call graph for this function:

void errWarn ( char *  function)

Definition at line 355 of file sslsample.c.

{
       PRErrorCode  errorNumber = PR_GetError();
       const char * errorString = SSL_Strerror(errorNumber);

       printf("Error in function %s: %d\n - %s\n",
                     function, errorNumber, errorString);
}

Here is the call graph for this function:

void exitErr ( char *  function)

Definition at line 365 of file sslsample.c.

{
       errWarn(function);
       /* Exit gracefully. */
       /* ignoring return value of NSS_Shutdown as code exits with 1*/
       (void) NSS_Shutdown();
       PR_Cleanup();
       exit(1);
}

Here is the call graph for this function:

SECStatus launch_thread ( GlobalThreadMgr threadMGR,
startFn startFunc,
void a,
int  b 
)

Definition at line 430 of file sslsample.c.

{
       perThread *slot;
       int        i;

       if (!threadMGR->threadStartQ) {
              threadMGR->threadLock   = PR_NewLock();
              threadMGR->threadStartQ = PR_NewCondVar(threadMGR->threadLock);
              threadMGR->threadEndQ   = PR_NewCondVar(threadMGR->threadLock);
       }
       PR_Lock(threadMGR->threadLock);
       while (threadMGR->numRunning >= MAX_THREADS) {
              PR_WaitCondVar(threadMGR->threadStartQ, PR_INTERVAL_NO_TIMEOUT);
       }
       for (i = 0; i < threadMGR->numUsed; ++i) {
              slot = &threadMGR->threads[i];
              if (slot->running == rs_idle) 
                     break;
       }
       if (i >= threadMGR->numUsed) {
              if (i >= MAX_THREADS) {
                     /* something's really wrong here. */
                     PORT_Assert(i < MAX_THREADS);
                     PR_Unlock(threadMGR->threadLock);
                     return SECFailure;
              }
              ++(threadMGR->numUsed);
              PORT_Assert(threadMGR->numUsed == i + 1);
              slot = &threadMGR->threads[i];
       }

       slot->a = a;
       slot->b = b;
       slot->startFunc = startFunc;

       threadMGR->index = i;

       slot->prThread = PR_CreateThread(PR_USER_THREAD,
                                        thread_wrapper, threadMGR,
                                        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
                                        PR_JOINABLE_THREAD, 0);

       if (slot->prThread == NULL) {
              PR_Unlock(threadMGR->threadLock);
              printf("Failed to launch thread!\n");
              return SECFailure;
       } 

       slot->inUse   = 1;
       slot->running = 1;
       ++(threadMGR->numRunning);
       PR_Unlock(threadMGR->threadLock);
       printf("Launched thread in slot %d \n", threadMGR->index);

       return SECSuccess;
}

Here is the call graph for this function:

int lockedVars_AddToCount ( lockedVars *  lv,
int  addend 
)

Definition at line 583 of file sslsample.c.

{
       int rv;

       PR_Lock(lv->lock);
       rv = lv->count += addend;
       if (rv <= 0) {
       PR_NotifyCondVar(lv->condVar);
       }
       PR_Unlock(lv->lock);
       return rv;
}

Here is the call graph for this function:

void lockedVars_Destroy ( lockedVars *  lv)

Definition at line 563 of file sslsample.c.

{
       PR_DestroyCondVar(lv->condVar);
       lv->condVar = NULL;

       PR_DestroyLock(lv->lock);
       lv->lock = NULL;
}

Here is the call graph for this function:

void lockedVars_Init ( lockedVars *  lv)

Definition at line 554 of file sslsample.c.

{
       lv->count     = 0;
       lv->waiters = 0;
       lv->lock      = PR_NewLock();
       lv->condVar = PR_NewCondVar(lv->lock);
}

Here is the call graph for this function:

void lockedVars_WaitForDone ( lockedVars *  lv)

Definition at line 573 of file sslsample.c.

{
       PR_Lock(lv->lock);
       while (lv->count > 0) {
              PR_WaitCondVar(lv->condVar, PR_INTERVAL_NO_TIMEOUT);
       }
       PR_Unlock(lv->lock);
}

Here is the call graph for this function:

SECStatus myAuthCertificate ( void arg,
PRFileDesc socket,
PRBool  checksig,
PRBool  isServer 
)

Definition at line 102 of file sslsample.c.

{

       SECCertUsage        certUsage;
       CERTCertificate *   cert;
       void *              pinArg;
       char *              hostName;
       SECStatus           secStatus;

       if (!arg || !socket) {
              errWarn("myAuthCertificate");
              return SECFailure;
       }

       /* Define how the cert is being used based upon the isServer flag. */

       certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;

       cert = SSL_PeerCertificate(socket);
       
       pinArg = SSL_RevealPinArg(socket);

       secStatus = CERT_VerifyCertNow((CERTCertDBHandle *)arg,
                                      cert,
                                      checksig,
                                      certUsage,
                                      pinArg);

       /* If this is a server, we're finished. */
       if (isServer || secStatus != SECSuccess) {
              CERT_DestroyCertificate(cert);
              return secStatus;
       }

       /* Certificate is OK.  Since this is the client side of an SSL
        * connection, we need to verify that the name field in the cert
        * matches the desired hostname.  This is our defense against
        * man-in-the-middle attacks.
        */

       /* SSL_RevealURL returns a hostName, not an URL. */
       hostName = SSL_RevealURL(socket);

       if (hostName && hostName[0]) {
              secStatus = CERT_VerifyCertName(cert, hostName);
       } else {
              PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0);
              secStatus = SECFailure;
       }

       if (hostName)
              PR_Free(hostName);

       CERT_DestroyCertificate(cert);
       return secStatus;
}

Here is the call graph for this function:

SECStatus myBadCertHandler ( void arg,
PRFileDesc socket 
)

Definition at line 170 of file sslsample.c.

{

    SECStatus secStatus = SECFailure;
    PRErrorCode      err;

    /* log invalid cert here */

    if (!arg) {
              return secStatus;
    }

    *(PRErrorCode *)arg = err = PORT_GetError();

    /* If any of the cases in the switch are met, then we will proceed   */
    /* with the processing of the request anyway. Otherwise, the default */  
    /* case will be reached and we will reject the request.              */

    switch (err) {
    case SEC_ERROR_INVALID_AVA:
    case SEC_ERROR_INVALID_TIME:
    case SEC_ERROR_BAD_SIGNATURE:
    case SEC_ERROR_EXPIRED_CERTIFICATE:
    case SEC_ERROR_UNKNOWN_ISSUER:
    case SEC_ERROR_UNTRUSTED_CERT:
    case SEC_ERROR_CERT_VALID:
    case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
    case SEC_ERROR_CRL_EXPIRED:
    case SEC_ERROR_CRL_BAD_SIGNATURE:
    case SEC_ERROR_EXTENSION_VALUE_INVALID:
    case SEC_ERROR_CA_CERT_INVALID:
    case SEC_ERROR_CERT_USAGES_INVALID:
    case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:
              secStatus = SECSuccess;
       break;
    default:
              secStatus = SECFailure;
       break;
    }

       printf("Bad certificate: %d, %s\n", err, SSL_Strerror(err));

    return secStatus;
}

Here is the call graph for this function:

SECStatus myGetClientAuthData ( void arg,
PRFileDesc socket,
struct CERTDistNamesStr caNames,
struct CERTCertificateStr **  pRetCert,
struct SECKEYPrivateKeyStr **  pRetKey 
)

Definition at line 221 of file sslsample.c.

{

    CERTCertificate *  cert;
    SECKEYPrivateKey * privKey;
    char *             chosenNickName = (char *)arg;
    void *             proto_win      = NULL;
    SECStatus          secStatus      = SECFailure;

    proto_win = SSL_RevealPinArg(socket);

    if (chosenNickName) {
              cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
              if (cert) {
                  privKey = PK11_FindKeyByAnyCert(cert, proto_win);
                  if (privKey) {
                            secStatus = SECSuccess;
                  } else {
                            CERT_DestroyCertificate(cert);
                  }
              }
    } else { /* no nickname given, automatically find the right cert */
       CERTCertNicknames *names;
       int                i;

       names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), 
                                  SEC_CERT_NICKNAMES_USER, proto_win);

       if (names != NULL) {
           for(i = 0; i < names->numnicknames; i++ ) {

              cert = PK11_FindCertFromNickname(names->nicknames[i], 
                                           proto_win);
              if (!cert) {
                  continue;
              }

              /* Only check unexpired certs */
              if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE)
                    != secCertTimeValid ) {
                  CERT_DestroyCertificate(cert);
                  continue;
              }

              secStatus = NSS_CmpCertChainWCANames(cert, caNames);
              if (secStatus == SECSuccess) {
                  privKey = PK11_FindKeyByAnyCert(cert, proto_win);
                  if (privKey) {
                     break;
                  }
                  secStatus = SECFailure;
                  break;
              }
           } /* for loop */
           CERT_FreeNicknames(names);
       }
    }

    if (secStatus == SECSuccess) {
              *pRetCert = cert;
              *pRetKey  = privKey;
    }

    return secStatus;
}

Here is the call graph for this function:

SECStatus myHandshakeCallback ( PRFileDesc socket,
void arg 
)

Definition at line 315 of file sslsample.c.

{
    printf("Handshake has completed, ready to send data securely.\n");
    return SECSuccess;
}
char* myPasswd ( PK11SlotInfo *  info,
PRBool  retry,
void arg 
)

Definition at line 83 of file sslsample.c.

{
       char * passwd = NULL;

       if ( (!retry) && arg ) {
              passwd = PORT_Strdup((char *)arg);
       }

       return passwd;
}

Here is the call graph for this function:

Definition at line 376 of file sslsample.c.

{
       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();

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

       printf("%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);

}

Here is the call graph for this function:

Definition at line 491 of file sslsample.c.

{
       perThread * slot;
       int                  i;

       if (!threadMGR->threadLock)
              return 0;
       PR_Lock(threadMGR->threadLock);
       while (threadMGR->numRunning > 0) {
           PR_WaitCondVar(threadMGR->threadEndQ, PR_INTERVAL_NO_TIMEOUT);
           for (i = 0; i < threadMGR->numUsed; ++i) {
              slot = &threadMGR->threads[i];
              if (slot->running == rs_zombie)  {
                  /* Handle cleanup of thread here. */
                  printf("Thread in slot %d returned %d\n", i, slot->rv);

                  /* Now make sure the thread has ended OK. */
                  PR_JoinThread(slot->prThread);
                  slot->running = rs_idle;
                  --threadMGR->numRunning;

                  /* notify the thread launcher. */
                  PR_NotifyCondVar(threadMGR->threadStartQ);
              }
           }
       }

       /* Safety Sam sez: make sure count is right. */
       for (i = 0; i < threadMGR->numUsed; ++i) {
              slot = &threadMGR->threads[i];
              if (slot->running != rs_idle)  {
                     fprintf(stderr, "Thread in slot %d is in state %d!\n", 
                                      i, slot->running);
              }
       }
       PR_Unlock(threadMGR->threadLock);
       return 0;
}

Here is the call graph for this function:

void thread_wrapper ( void arg)

Definition at line 409 of file sslsample.c.

{
       GlobalThreadMgr *threadMGR = (GlobalThreadMgr *)arg;
       perThread *slot = &threadMGR->threads[threadMGR->index];

       /* wait for parent to finish launching us before proceeding. */
       PR_Lock(threadMGR->threadLock);
       PR_Unlock(threadMGR->threadLock);

       slot->rv = (* slot->startFunc)(slot->a, slot->b);

       PR_Lock(threadMGR->threadLock);
       slot->running = rs_zombie;

       /* notify the thread exit handler. */
       PR_NotifyCondVar(threadMGR->threadEndQ);

       PR_Unlock(threadMGR->threadLock);
}

Here is the call graph for this function:


Variable Documentation