security/nss/cmd/certutil/keystuff.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include <stdio.h>
     6 #include <string.h>
     7 #include "secutil.h"
     9 #if defined(XP_UNIX)
    10 #include <unistd.h>
    11 #include <sys/time.h>
    12 #include <termios.h>
    13 #endif
    15 #if defined(XP_WIN) || defined (XP_PC)
    16 #include <time.h>
    17 #include <conio.h>
    18 #endif
    20 #if defined(__sun) && !defined(SVR4)
    21 extern int fclose(FILE*);
    22 extern int fprintf(FILE *, char *, ...);
    23 extern int isatty(int);
    24 extern char *sys_errlist[];
    25 #define strerror(errno) sys_errlist[errno]
    26 #endif
    28 #include "nspr.h"
    29 #include "prtypes.h"
    30 #include "prtime.h"
    31 #include "prlong.h"
    33 #include "pk11func.h"
    35 #define NUM_KEYSTROKES 120
    36 #define RAND_BUF_SIZE 60
    38 #define ERROR_BREAK rv = SECFailure;break;
    40 const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
    41     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
    42     { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
    43     { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
    44     { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
    45     { 0, }
    46 };
    48 /* returns 0 for success, -1 for failure (EOF encountered) */
    49 static int
    50 UpdateRNG(void)
    51 {
    52     char           randbuf[RAND_BUF_SIZE];
    53     int            fd,  count;
    54     int            c;
    55     int            rv		= 0;
    56 #ifdef XP_UNIX
    57     cc_t           orig_cc_min;
    58     cc_t           orig_cc_time;
    59     tcflag_t       orig_lflag;
    60     struct termios tio;
    61 #endif
    62     char meter[] = { 
    63       "\r|                                                            |" };
    65 #define FPS fprintf(stderr, 
    66     FPS "\n");
    67     FPS "A random seed must be generated that will be used in the\n");
    68     FPS "creation of your key.  One of the easiest ways to create a\n");
    69     FPS "random seed is to use the timing of keystrokes on a keyboard.\n");
    70     FPS "\n");
    71     FPS "To begin, type keys on the keyboard until this progress meter\n");
    72     FPS "is full.  DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!\n");
    73     FPS "\n");
    74     FPS "\n");
    75     FPS "Continue typing until the progress meter is full:\n\n");
    76     FPS "%s", meter);
    77     FPS "\r|");
    79     /* turn off echo on stdin & return on 1 char instead of NL */
    80     fd = fileno(stdin);
    82 #if defined(XP_UNIX)
    83     tcgetattr(fd, &tio);
    84     orig_lflag = tio.c_lflag;
    85     orig_cc_min = tio.c_cc[VMIN];
    86     orig_cc_time = tio.c_cc[VTIME];
    87     tio.c_lflag &= ~ECHO;
    88     tio.c_lflag &= ~ICANON;
    89     tio.c_cc[VMIN] = 1;
    90     tio.c_cc[VTIME] = 0;
    91     tcsetattr(fd, TCSAFLUSH, &tio);
    92 #endif
    94     /* Get random noise from keyboard strokes */
    95     count = 0;
    96     while (count < sizeof randbuf) {
    97 #if defined(XP_UNIX)
    98 	c = getc(stdin);
    99 #else
   100 	c = getch();
   101 #endif
   102 	if (c == EOF) {
   103 	    rv = -1;
   104 	    break;
   105 	}
   106 	randbuf[count] = c;
   107 	if (count == 0 || c != randbuf[count-1]) {
   108 	    count++;
   109 	    FPS "*");
   110 	}
   111     }
   112     PK11_RandomUpdate(randbuf, sizeof randbuf);
   113     memset(randbuf, 0, sizeof randbuf);
   115     FPS "\n\n");
   116     FPS "Finished.  Press enter to continue: ");
   117     while ((c = getc(stdin)) != '\n' && c != EOF)
   118 	;
   119     if (c == EOF) 
   120 	rv = -1;
   121     FPS "\n");
   123 #undef FPS
   125 #if defined(XP_UNIX)
   126     /* set back termio the way it was */
   127     tio.c_lflag = orig_lflag;
   128     tio.c_cc[VMIN] = orig_cc_min;
   129     tio.c_cc[VTIME] = orig_cc_time;
   130     tcsetattr(fd, TCSAFLUSH, &tio);
   131 #endif
   132     return rv;
   133 }
   135 static const unsigned char P[] = { 0, 
   136        0x98, 0xef, 0x3a, 0xae, 0x70, 0x98, 0x9b, 0x44, 
   137        0xdb, 0x35, 0x86, 0xc1, 0xb6, 0xc2, 0x47, 0x7c, 
   138        0xb4, 0xff, 0x99, 0xe8, 0xae, 0x44, 0xf2, 0xeb, 
   139        0xc3, 0xbe, 0x23, 0x0f, 0x65, 0xd0, 0x4c, 0x04, 
   140        0x82, 0x90, 0xa7, 0x9d, 0x4a, 0xc8, 0x93, 0x7f, 
   141        0x41, 0xdf, 0xf8, 0x80, 0x6b, 0x0b, 0x68, 0x7f, 
   142        0xaf, 0xe4, 0xa8, 0xb5, 0xb2, 0x99, 0xc3, 0x69, 
   143        0xfb, 0x3f, 0xe7, 0x1b, 0xd0, 0x0f, 0xa9, 0x7a, 
   144        0x4a, 0x04, 0xbf, 0x50, 0x9e, 0x22, 0x33, 0xb8, 
   145        0x89, 0x53, 0x24, 0x10, 0xf9, 0x68, 0x77, 0xad, 
   146        0xaf, 0x10, 0x68, 0xb8, 0xd3, 0x68, 0x5d, 0xa3, 
   147        0xc3, 0xeb, 0x72, 0x3b, 0xa0, 0x0b, 0x73, 0x65, 
   148        0xc5, 0xd1, 0xfa, 0x8c, 0xc0, 0x7d, 0xaa, 0x52, 
   149        0x29, 0x34, 0x44, 0x01, 0xbf, 0x12, 0x25, 0xfe, 
   150        0x18, 0x0a, 0xc8, 0x3f, 0xc1, 0x60, 0x48, 0xdb, 
   151        0xad, 0x93, 0xb6, 0x61, 0x67, 0xd7, 0xa8, 0x2d };
   152 static const unsigned char Q[] = { 0,
   153        0xb5, 0xb0, 0x84, 0x8b, 0x44, 0x29, 0xf6, 0x33, 
   154        0x59, 0xa1, 0x3c, 0xbe, 0xd2, 0x7f, 0x35, 0xa1, 
   155        0x76, 0x27, 0x03, 0x81                         };
   156 static const unsigned char G[] = { 
   157        0x04, 0x0e, 0x83, 0x69, 0xf1, 0xcd, 0x7d, 0xe5, 
   158        0x0c, 0x78, 0x93, 0xd6, 0x49, 0x6f, 0x00, 0x04, 
   159        0x4e, 0x0e, 0x6c, 0x37, 0xaa, 0x38, 0x22, 0x47, 
   160        0xd2, 0x58, 0xec, 0x83, 0x12, 0x95, 0xf9, 0x9c, 
   161        0xf1, 0xf4, 0x27, 0xff, 0xd7, 0x99, 0x57, 0x35, 
   162        0xc6, 0x64, 0x4c, 0xc0, 0x47, 0x12, 0x31, 0x50, 
   163        0x82, 0x3c, 0x2a, 0x07, 0x03, 0x01, 0xef, 0x30, 
   164        0x09, 0x89, 0x82, 0x41, 0x76, 0x71, 0xda, 0x9e, 
   165        0x57, 0x8b, 0x76, 0x38, 0x37, 0x5f, 0xa5, 0xcd, 
   166        0x32, 0x84, 0x45, 0x8d, 0x4c, 0x17, 0x54, 0x2b, 
   167        0x5d, 0xc2, 0x6b, 0xba, 0x3e, 0xa0, 0x7b, 0x95, 
   168        0xd7, 0x00, 0x42, 0xf7, 0x08, 0xb8, 0x83, 0x87, 
   169        0x60, 0xe1, 0xe5, 0xf4, 0x1a, 0x54, 0xc2, 0x20, 
   170        0xda, 0x38, 0x3a, 0xd1, 0xb6, 0x10, 0xf4, 0xcb, 
   171        0x35, 0xda, 0x97, 0x92, 0x87, 0xd6, 0xa5, 0x37, 
   172        0x62, 0xb4, 0x93, 0x4a, 0x15, 0x21, 0xa5, 0x10 };
   174 /*  h:
   175  *      4a:76:30:89:eb:e1:81:7c:99:0b:39:7f:95:4a:65:72:
   176  *      c6:b4:05:92:48:6c:3c:b2:7e:e7:39:f3:92:7d:c1:3f:
   177  *      bf:e1:fd:b3:4a:46:3e:ce:29:80:e3:d6:f4:59:c6:92:
   178  *      16:2b:0e:d7:d6:bb:ef:94:36:31:c2:66:46:c5:4a:77:
   179  *      aa:95:84:ef:99:7e:e3:9c:d9:a0:32:42:09:b6:4e:d0:
   180  *      b3:c8:5e:06:df:a1:ac:4d:2d:f9:08:c2:cb:4b:a4:42:
   181  *      db:8a:5b:de:25:6e:2b:5b:ca:00:75:2c:57:00:18:aa:
   182  *      68:59:a1:94:03:07:94:78:38:bc:f8:7c:1e:1c:a3:2e
   183  *  SEED:
   184  *      b5:44:66:c9:0f:f1:ca:1c:95:45:ce:90:74:89:14:f2:
   185  *      13:3e:23:5a:b0:6a:bf:86:ad:cb:a0:7d:ce:3b:c8:16:
   186  *      7f:2d:a2:1a:cb:33:7d:c1:e7:d7:07:aa:1b:a2:d7:89:
   187  *      f5:a4:db:f7:8b:50:00:cd:b4:7d:25:81:3f:f8:a8:dd:
   188  *      6c:46:e5:77:b5:60:7e:75:79:b8:99:57:c1:c4:f3:f7:
   189  *      17:ca:43:00:b8:33:b6:06:8f:4d:91:ed:23:a5:66:1b:
   190  *      ef:14:d7:bc:21:2b:82:d8:ab:fa:fd:a7:c3:4d:bf:52:
   191  *      af:8e:57:59:61:1a:4e:65:c6:90:d6:a6:ff:0b:15:b1
   192  *  g:       1024
   193  *  counter: 1003
   194  */
   196 static const SECKEYPQGParams default_pqg_params = {
   197     NULL,
   198     { 0, (unsigned char *)P, sizeof(P) },
   199     { 0, (unsigned char *)Q, sizeof(Q) },
   200     { 0, (unsigned char *)G, sizeof(G) }
   201 };
   203 static SECKEYPQGParams *
   204 decode_pqg_params(const char *str)
   205 {
   206     char *buf;
   207     unsigned int len;
   208     PLArenaPool *arena;
   209     SECKEYPQGParams *params;
   210     SECStatus status;
   212     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   213     if (arena == NULL)
   214         return NULL;
   216     params = PORT_ArenaZAlloc(arena, sizeof(SECKEYPQGParams));
   217     if (params == NULL)
   218         goto loser;
   219     params->arena = arena;
   221     buf = (char *)ATOB_AsciiToData(str, &len);
   222     if ((buf == NULL) || (len == 0))
   223         goto loser;
   225     status = SEC_ASN1Decode(arena, params, SECKEY_PQGParamsTemplate, buf, len);
   226     if (status != SECSuccess)
   227         goto loser;
   229     return params;
   231 loser:
   232     if (arena != NULL)
   233         PORT_FreeArena(arena, PR_FALSE);
   234     return NULL;
   235 }
   237 void  
   238 CERTUTIL_DestroyParamsPQG(SECKEYPQGParams *params)
   239 {
   240     if (params->arena) {
   241         PORT_FreeArena(params->arena, PR_FALSE);
   242     }
   243 }
   245 static int
   246 pqg_prime_bits(const SECKEYPQGParams *params)
   247 {
   248     int primeBits = 0;
   250     if (params != NULL) {
   251 	int i;
   252 	for (i = 0; params->prime.data[i] == 0; i++) {
   253 	    /* empty */;
   254 	}
   255 	primeBits = (params->prime.len - i) * 8;
   256     }
   258     return primeBits;
   259 }
   261 static char *
   262 getPQGString(const char *filename)
   263 {
   264     unsigned char *buf      = NULL;
   265     PRFileDesc    *src;
   266     PRInt32        numBytes;
   267     PRStatus       prStatus;
   268     PRFileInfo     info;
   270     src   = PR_Open(filename, PR_RDONLY, 0);
   271     if (!src) {
   272     	fprintf(stderr, "Failed to open PQG file %s\n", filename);
   273 	return NULL;
   274     }
   276     prStatus = PR_GetOpenFileInfo(src, &info);
   278     if (prStatus == PR_SUCCESS) {
   279 	buf = (unsigned char*)PORT_Alloc(info.size + 1);
   280     }
   281     if (!buf) {
   282 	PR_Close(src);
   283     	fprintf(stderr, "Failed to read PQG file %s\n", filename);
   284 	return NULL;
   285     }
   287     numBytes = PR_Read(src, buf, info.size);
   288     PR_Close(src);
   289     if (numBytes != info.size) {
   290 	PORT_Free(buf);
   291     	fprintf(stderr, "Failed to read PQG file %s\n", filename);
   292 	PORT_SetError(SEC_ERROR_IO);
   293 	return NULL;
   294     }
   296     if (buf[numBytes-1] == '\n') 
   297     	numBytes--;
   298     if (buf[numBytes-1] == '\r') 
   299     	numBytes--;
   300     buf[numBytes] = 0;
   302     return (char *)buf;
   303 }
   305 static SECKEYPQGParams*
   306 getpqgfromfile(int keyBits, const char *pqgFile)
   307 {
   308     char *end, *str, *pqgString;
   309     SECKEYPQGParams* params = NULL;
   311     str = pqgString = getPQGString(pqgFile);
   312     if (!str) 
   313 	return NULL;
   315     do {
   316 	end = PORT_Strchr(str, ',');
   317 	if (end)
   318 	    *end = '\0';
   319 	params = decode_pqg_params(str);
   320 	if (params) {
   321 	    int primeBits = pqg_prime_bits(params);
   322 	    if (keyBits == primeBits)
   323 		break;
   324 	    CERTUTIL_DestroyParamsPQG(params);
   325 	    params = NULL;
   326 	}
   327 	if (end)
   328 	    str = end + 1;
   329     } while (end);
   331     PORT_Free(pqgString);
   332     return params;
   333 }
   335 static SECStatus 
   336 CERTUTIL_FileForRNG(const char *noise)
   337 {
   338     char buf[2048];
   339     PRFileDesc *fd;
   340     PRInt32 count;
   342     fd = PR_Open(noise,PR_RDONLY,0);
   343     if (!fd) {
   344 	fprintf(stderr, "failed to open noise file.");
   345 	return SECFailure;
   346     }
   348     do {
   349 	count = PR_Read(fd,buf,sizeof(buf));
   350 	if (count > 0) {
   351 	    PK11_RandomUpdate(buf,count);
   352 	}
   353     } while (count > 0);
   355     PR_Close(fd);
   356     return SECSuccess;
   357 }
   359 #ifndef NSS_DISABLE_ECC
   360 typedef struct curveNameTagPairStr {
   361     char *curveName;
   362     SECOidTag curveOidTag;
   363 } CurveNameTagPair;
   365 #define DEFAULT_CURVE_OID_TAG  SEC_OID_SECG_EC_SECP192R1
   366 /* #define DEFAULT_CURVE_OID_TAG  SEC_OID_SECG_EC_SECP160R1 */
   368 static CurveNameTagPair nameTagPair[] =
   369 { 
   370   { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
   371   { "nistk163", SEC_OID_SECG_EC_SECT163K1},
   372   { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
   373   { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
   374   { "nistb163", SEC_OID_SECG_EC_SECT163R2},
   375   { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
   376   { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
   377   { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
   378   { "nistk233", SEC_OID_SECG_EC_SECT233K1},
   379   { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
   380   { "nistb233", SEC_OID_SECG_EC_SECT233R1},
   381   { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
   382   { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
   383   { "nistk283", SEC_OID_SECG_EC_SECT283K1},
   384   { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
   385   { "nistb283", SEC_OID_SECG_EC_SECT283R1},
   386   { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
   387   { "nistk409", SEC_OID_SECG_EC_SECT409K1},
   388   { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
   389   { "nistb409", SEC_OID_SECG_EC_SECT409R1},
   390   { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
   391   { "nistk571", SEC_OID_SECG_EC_SECT571K1},
   392   { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
   393   { "nistb571", SEC_OID_SECG_EC_SECT571R1},
   394   { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
   395   { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
   396   { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
   397   { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
   398   { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
   399   { "nistp192", SEC_OID_SECG_EC_SECP192R1},
   400   { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
   401   { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
   402   { "nistp224", SEC_OID_SECG_EC_SECP224R1},
   403   { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
   404   { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
   405   { "nistp256", SEC_OID_SECG_EC_SECP256R1},
   406   { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
   407   { "nistp384", SEC_OID_SECG_EC_SECP384R1},
   408   { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
   409   { "nistp521", SEC_OID_SECG_EC_SECP521R1},
   411   { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
   412   { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
   413   { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
   414   { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
   415   { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
   416   { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
   418   { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
   419   { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
   420   { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
   421   { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
   422   { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
   423   { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
   424   { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
   425   { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
   426   { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
   427   { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
   428   { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
   429   { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
   430   { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
   431   { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
   432   { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
   433   { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
   434   { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
   435   { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
   436   { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
   437   { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
   439   { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
   440   { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
   441   { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
   442   { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
   444   { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
   445   { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
   446   { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
   447   { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
   448 };
   450 static SECKEYECParams * 
   451 getECParams(const char *curve)
   452 {
   453     SECKEYECParams *ecparams;
   454     SECOidData *oidData = NULL;
   455     SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
   456     int i, numCurves;
   458     if (curve != NULL) {
   459         numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
   460 	for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
   461 	     i++) {
   462 	    if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
   463 	        curveOidTag = nameTagPair[i].curveOidTag;
   464 	}
   465     }
   467     /* Return NULL if curve name is not recognized */
   468     if ((curveOidTag == SEC_OID_UNKNOWN) || 
   469 	(oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
   470         fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
   471 	return NULL;
   472     }
   474     ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
   476     /* 
   477      * ecparams->data needs to contain the ASN encoding of an object ID (OID)
   478      * representing the named curve. The actual OID is in 
   479      * oidData->oid.data so we simply prepend 0x06 and OID length
   480      */
   481     ecparams->data[0] = SEC_ASN1_OBJECT_ID;
   482     ecparams->data[1] = oidData->oid.len;
   483     memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
   485     return ecparams;
   486 }
   487 #endif /* NSS_DISABLE_ECC */
   489 SECKEYPrivateKey *
   490 CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size,
   491 			    int publicExponent, const char *noise, 
   492 			    SECKEYPublicKey **pubkeyp, const char *pqgFile,
   493 			    PK11AttrFlags attrFlags, CK_FLAGS opFlagsOn,
   494 			    CK_FLAGS opFlagsOff, secuPWData *pwdata)
   495 {
   496     CK_MECHANISM_TYPE  mechanism;
   497     SECOidTag          algtag;
   498     PK11RSAGenParams   rsaparams;
   499     SECKEYPQGParams  * dsaparams = NULL;
   500     void             * params;
   501     SECKEYPrivateKey * privKey = NULL;
   503     if (slot == NULL)
   504 	return NULL;
   506     if (PK11_Authenticate(slot, PR_TRUE, pwdata) != SECSuccess)
   507 	return NULL;
   509     /*
   510      * Do some random-number initialization.
   511      */
   513     if (noise) {
   514     	SECStatus rv = CERTUTIL_FileForRNG(noise);
   515 	if (rv != SECSuccess) {
   516 	    PORT_SetError(PR_END_OF_FILE_ERROR); /* XXX */
   517 	    return NULL;
   518     	}
   519     } else {
   520 	int rv = UpdateRNG();
   521 	if (rv) {
   522 	    PORT_SetError(PR_END_OF_FILE_ERROR);
   523 	    return NULL;
   524 	}
   525     }
   527     switch (keytype) {
   528     case rsaKey:
   529 	rsaparams.keySizeInBits = size;
   530 	rsaparams.pe = publicExponent;
   531 	mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
   532 	algtag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
   533 	params = &rsaparams;
   534 	break;
   535     case dsaKey:
   536 	mechanism = CKM_DSA_KEY_PAIR_GEN;
   537 	algtag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
   538 	if (pqgFile) {
   539 	    dsaparams = getpqgfromfile(size, pqgFile);
   540 	    if (dsaparams == NULL)
   541 	    	return NULL;
   542 	    params = dsaparams;
   543 	} else {
   544 	    /* cast away const, and don't set dsaparams */
   545 	    params = (void *)&default_pqg_params;
   546 	}
   547 	break;
   548 #ifndef NSS_DISABLE_ECC
   549     case ecKey:
   550 	mechanism = CKM_EC_KEY_PAIR_GEN;
   551 	/* For EC keys, PQGFile determines EC parameters */
   552 	if ((params = (void *) getECParams(pqgFile)) == NULL)
   553 	    return NULL;
   554 	break;
   555 #endif /* NSS_DISABLE_ECC */
   556     default:
   557 	return NULL;
   558     }
   560     fprintf(stderr, "\n\n");
   561     fprintf(stderr, "Generating key.  This may take a few moments...\n\n");
   563     privKey = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubkeyp,
   564 				attrFlags, opFlagsOn, opFlagsOn|opFlagsOff,
   565 				pwdata /*wincx*/);
   566     /* free up the params */
   567     switch (keytype) {
   568     case dsaKey: if (dsaparams) CERTUTIL_DestroyParamsPQG(dsaparams); 
   569 	                                                      break;
   570 #ifndef NSS_DISABLE_ECC
   571     case ecKey: SECITEM_FreeItem((SECItem *)params, PR_TRUE); break;
   572 #endif
   573     default: /* nothing to free */                            break;
   574     }
   575     return privKey;
   576 }

mercurial