Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
keystuff.c File Reference
#include <stdio.h>
#include <string.h>
#include "secutil.h"
#include "nspr.h"
#include "prtypes.h"
#include "prtime.h"
#include "prlong.h"
#include "pk11func.h"

Go to the source code of this file.


#define NUM_KEYSTROKES   120
#define RAND_BUF_SIZE   60
#define ERROR_BREAK   rv = SECFailure;break;
#define FPS   fprintf(stderr,


static int UpdateRNG (void)
static SECKEYPQGParams * decode_pqg_params (const char *str)
void CERTUTIL_DestroyParamsPQG (SECKEYPQGParams *params)
static int pqg_prime_bits (const SECKEYPQGParams *params)
static char * getPQGString (const char *filename)
static SECKEYPQGParams * getpqgfromfile (int keyBits, const char *pqgFile)
static SECStatus CERTUTIL_FileForRNG (const char *noise)
SECKEYPrivateKey * CERTUTIL_GeneratePrivateKey (KeyType keytype, PK11SlotInfo *slot, int size, int publicExponent, const char *noise, SECKEYPublicKey **pubkeyp, const char *pqgFile, secuPWData *pwdata)


const SEC_ASN1Template SECKEY_PQGParamsTemplate []
static const unsigned char P []
static const unsigned char Q []
static const unsigned char G []
static const SECKEYPQGParams default_pqg_params

Define Documentation

Definition at line 71 of file keystuff.c.

#define FPS   fprintf(stderr,

Definition at line 68 of file keystuff.c.

Definition at line 69 of file keystuff.c.

Function Documentation

void CERTUTIL_DestroyParamsPQG ( SECKEYPQGParams *  params)

Definition at line 246 of file keystuff.c.

    if (params->arena) {
        PORT_FreeArena(params->arena, PR_FALSE);

Here is the call graph for this function:

static SECStatus CERTUTIL_FileForRNG ( const char *  noise) [static]

Definition at line 344 of file keystuff.c.

    char buf[2048];
    PRFileDesc *fd;
    PRInt32 count;

    fd = PR_Open(noise,PR_RDONLY,0);
    if (!fd) {
       fprintf(stderr, "failed to open noise file.");
       return SECFailure;

    do {
       count = PR_Read(fd,buf,sizeof(buf));
       if (count > 0) {
    } while (count > 0);

    return SECSuccess;

Here is the call graph for this function:

Here is the caller graph for this function:

SECKEYPrivateKey* CERTUTIL_GeneratePrivateKey ( KeyType  keytype,
PK11SlotInfo *  slot,
int  size,
int  publicExponent,
const char *  noise,
SECKEYPublicKey **  pubkeyp,
const char *  pqgFile,
secuPWData pwdata 

Definition at line 498 of file keystuff.c.

    CK_MECHANISM_TYPE  mechanism;
    SECOidTag          algtag;
    PK11RSAGenParams   rsaparams;
    SECKEYPQGParams  * dsaparams = NULL;
    void             * params;
    SECKEYPrivateKey * privKey = NULL;

    if (slot == NULL)
       return NULL;

    if (PK11_Authenticate(slot, PR_TRUE, pwdata) != SECSuccess)
       return NULL;

     * Do some random-number initialization.

    if (noise) {
       SECStatus rv = CERTUTIL_FileForRNG(noise);
       if (rv != SECSuccess) {
           PORT_SetError(PR_END_OF_FILE_ERROR); /* XXX */
           return NULL;
    } else {
       int rv = UpdateRNG();
       if (rv) {
           return NULL;

    switch (keytype) {
    case rsaKey:
       rsaparams.keySizeInBits = size; = publicExponent;
       mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
       params = &rsaparams;
    case dsaKey:
       mechanism = CKM_DSA_KEY_PAIR_GEN;
       if (pqgFile) {
           dsaparams = getpqgfromfile(size, pqgFile);
           if (dsaparams == NULL)
              return NULL;
           params = dsaparams;
       } else {
           /* cast away const, and don't set dsaparams */
           params = (void *)&default_pqg_params;
    case ecKey:
       mechanism = CKM_EC_KEY_PAIR_GEN;
       /* For EC keys, PQGFile determines EC parameters */
       if ((params = (void *) getECParams(pqgFile)) == NULL)
           return NULL;
#endif /* NSS_ENABLE_ECC */
       return NULL;

    fprintf(stderr, "\n\n");
    fprintf(stderr, "Generating key.  This may take a few moments...\n\n");

    privKey = PK11_GenerateKeyPair(slot, mechanism, params, pubkeyp,
                            PR_TRUE /*isPerm*/, PR_TRUE /*isSensitive*/, 
                            pwdata /*wincx*/);
    /* free up the params */
    switch (keytype) {
    case rsaKey: /* nothing to free */                        break;
    case dsaKey: if (dsaparams) CERTUTIL_DestroyParamsPQG(dsaparams); 
    case ecKey: SECITEM_FreeItem((SECItem *)params, PR_TRUE); break;
    return privKey;

Here is the call graph for this function:

static SECKEYPQGParams* decode_pqg_params ( const char *  str) [static]

Definition at line 212 of file keystuff.c.

    char *buf;
    unsigned int len;
    PRArenaPool *arena;
    SECKEYPQGParams *params;
    SECStatus status;
    if (arena == NULL)
        return NULL;
    params = PORT_ArenaZAlloc(arena, sizeof(SECKEYPQGParams));
    if (params == NULL)
        goto loser;
    params->arena = arena;
    buf = (char *)ATOB_AsciiToData(str, &len);
    if ((buf == NULL) || (len == 0))
        goto loser;
    status = SEC_ASN1Decode(arena, params, SECKEY_PQGParamsTemplate, buf, len);
    if (status != SECSuccess)
        goto loser;
    return params;
    if (arena != NULL)
        PORT_FreeArena(arena, PR_FALSE);
    return NULL;

Here is the call graph for this function:

Here is the caller graph for this function:

static SECKEYPQGParams* getpqgfromfile ( int  keyBits,
const char *  pqgFile 
) [static]

Definition at line 314 of file keystuff.c.

    char *end, *str, *pqgString;
    SECKEYPQGParams* params = NULL;

    str = pqgString = getPQGString(pqgFile);
    if (!str) 
       return NULL;

    do {
       end = PORT_Strchr(str, ',');
       if (end)
           *end = '\0';
       params = decode_pqg_params(str);
       if (params) {
           int primeBits = pqg_prime_bits(params);
           if (keyBits == primeBits)
           params = NULL;
       if (end)
           str = end + 1;
    } while (end);

    return params;

Here is the call graph for this function:

Here is the caller graph for this function:

static char* getPQGString ( const char *  filename) [static]

Definition at line 270 of file keystuff.c.

    unsigned char *buf      = NULL;
    PRFileDesc    *src;
    PRInt32        numBytes;
    PRStatus       prStatus;
    PRFileInfo     info;

    src   = PR_Open(filename, PR_RDONLY, 0);
    if (!src) {
       fprintf(stderr, "Failed to open PQG file %s\n", filename);
       return NULL;

    prStatus = PR_GetOpenFileInfo(src, &info);

    if (prStatus == PR_SUCCESS) {
       buf = (unsigned char*)PORT_Alloc(info.size + 1);
    if (!buf) {
       fprintf(stderr, "Failed to read PQG file %s\n", filename);
       return NULL;

    numBytes = PR_Read(src, buf, info.size);
    if (numBytes != info.size) {
       fprintf(stderr, "Failed to read PQG file %s\n", filename);
       return NULL;

    if (buf[numBytes-1] == '\n') 
    if (buf[numBytes-1] == '\r') 
    buf[numBytes] = 0;
    return (char *)buf;

Here is the call graph for this function:

Here is the caller graph for this function:

static int pqg_prime_bits ( const SECKEYPQGParams *  params) [static]

Definition at line 254 of file keystuff.c.

    int primeBits = 0;
    if (params != NULL) {
       int i;
       for (i = 0; params->[i] == 0; i++) {
           /* empty */;
       primeBits = (params->prime.len - i) * 8;
    return primeBits;

Here is the caller graph for this function:

static int UpdateRNG ( void  ) [static]

Definition at line 83 of file keystuff.c.

    char *         randbuf;
    int            fd, i, count;
    int            c;
    int            rv              = 0;
#ifdef XP_UNIX
    cc_t           orig_cc_min;
    cc_t           orig_cc_time;
    tcflag_t       orig_lflag;
    struct termios tio;

#define FPS fprintf(stderr, 
    FPS "\n");
    FPS "A random seed must be generated that will be used in the\n");
    FPS "creation of your key.  One of the easiest ways to create a\n");
    FPS "random seed is to use the timing of keystrokes on a keyboard.\n");
    FPS "\n");
    FPS "To begin, type keys on the keyboard until this progress meter\n");
    FPS "\n");
    FPS "\n");
    FPS "Continue typing until the progress meter is full:\n\n");
    FPS "|                                                            |\r");

    /* turn off echo on stdin & return on 1 char instead of NL */
    fd = fileno(stdin);

#if defined(XP_UNIX) && !defined(VMS)
    tcgetattr(fd, &tio);
    orig_lflag = tio.c_lflag;
    orig_cc_min = tio.c_cc[VMIN];
    orig_cc_time = tio.c_cc[VTIME];
    tio.c_lflag &= ~ECHO;
    tio.c_lflag &= ~ICANON;
    tio.c_cc[VMIN] = 1;
    tio.c_cc[VTIME] = 0;
    tcsetattr(fd, TCSAFLUSH, &tio);

    /* Get random noise from keyboard strokes */
    randbuf = (char *) PORT_Alloc(RAND_BUF_SIZE);
    count = 0;
    while (count < NUM_KEYSTROKES+1) {
#ifdef VMS
#elif XP_UNIX
       c = getc(stdin);
       c = getch();
       if (c == EOF) {
           rv = -1;
       PK11_RandomUpdate(randbuf, sizeof(randbuf));
       if (c != randbuf[0]) {
           randbuf[0] = c;
           FPS "\r|");
           for (i=0; i<count/(NUM_KEYSTROKES/RAND_BUF_SIZE); i++) {
              FPS "*");
           if (count%(NUM_KEYSTROKES/RAND_BUF_SIZE) == 1)
              FPS "/");

    FPS "\n\n");
    FPS "Finished.  Press enter to continue: ");
#if defined(VMS)
    while((c = GENERIC_GETCHAR_NO_ECHO()) != '\r' && c != EOF)
    while ((c = getc(stdin)) != '\n' && c != EOF)
    if (c == EOF) 
       rv = -1;
    FPS "\n");

#undef FPS

#if defined(XP_UNIX) && !defined(VMS)
    /* set back termio the way it was */
    tio.c_lflag = orig_lflag;
    tio.c_cc[VMIN] = orig_cc_min;
    tio.c_cc[VTIME] = orig_cc_time;
    tcsetattr(fd, TCSAFLUSH, &tio);
    return rv;

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

const SECKEYPQGParams default_pqg_params [static]
Initial value:
    { 0, (unsigned char *)P, sizeof(P) },
    { 0, (unsigned char *)Q, sizeof(Q) },
    { 0, (unsigned char *)G, sizeof(G) }

Definition at line 204 of file keystuff.c.

const unsigned char G[] [static]
Initial value:
                           { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
                          0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
                          0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
                          0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
                          0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
                          0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
                          0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
                          0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
                          0x02 }

Definition at line 193 of file keystuff.c.

const unsigned char P[] [static]
Initial value:
                           { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
                          0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
                          0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
                          0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
                          0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
                          0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
                          0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
                          0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
                          0x91 }

Definition at line 179 of file keystuff.c.

const unsigned char Q[] [static]
Initial value:
                           { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
                          0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
                          0x8e, 0xda, 0xce, 0x91, 0x5f }

Definition at line 189 of file keystuff.c.

Initial value:
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
    { 0, }

Definition at line 73 of file keystuff.c.