keystuff.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:13k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include "secutil.h"
  36. #if defined(XP_UNIX)
  37. #include <unistd.h>
  38. #include <sys/time.h>
  39. #include <termios.h>
  40. #endif
  41. #if defined(XP_WIN) || defined (XP_PC)
  42. #include <time.h>
  43. #include <conio.h>
  44. #endif
  45. #if defined(__sun) && !defined(SVR4)
  46. extern int fclose(FILE*);
  47. extern int fprintf(FILE *, char *, ...);
  48. extern int isatty(int);
  49. extern char *sys_errlist[];
  50. #define strerror(errno) sys_errlist[errno]
  51. #endif
  52. #include "nspr.h"
  53. #include "prtypes.h"
  54. #include "prtime.h"
  55. #include "prlong.h"
  56. #include "pk11func.h"
  57. #include "secrng.h"
  58. #include "pqgutil.h"
  59. #define NUM_KEYSTROKES 120
  60. #define RAND_BUF_SIZE 60
  61. #define ERROR_BREAK rv = SECFailure;break;
  62. static void
  63. UpdateRNG(void)
  64. {
  65.     char *         randbuf;
  66.     int            fd, i, count;
  67.     char           c;
  68. #ifdef XP_UNIX
  69.     cc_t           orig_cc_min;
  70.     cc_t           orig_cc_time;
  71.     tcflag_t       orig_lflag;
  72.     struct termios tio;
  73. #endif
  74. #define FPS fprintf(stderr, 
  75.     FPS "n");
  76.     FPS "A random seed must be generated that will be used in then");
  77.     FPS "creation of your key.  One of the easiest ways to create an");
  78.     FPS "random seed is to use the timing of keystrokes on a keyboard.n");
  79.     FPS "n");
  80.     FPS "To begin, type keys on the keyboard until this progress metern");
  81.     FPS "is full.  DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!n");
  82.     FPS "n");
  83.     FPS "n");
  84.     FPS "Continue typing until the progress meter is full:nn");
  85.     FPS "|                                                            |r");
  86.     /* turn off echo on stdin & return on 1 char instead of NL */
  87.     fd = fileno(stdin);
  88. #ifdef XP_UNIX
  89.     tcgetattr(fd, &tio);
  90.     orig_lflag = tio.c_lflag;
  91.     orig_cc_min = tio.c_cc[VMIN];
  92.     orig_cc_time = tio.c_cc[VTIME];
  93.     tio.c_lflag &= ~ECHO;
  94.     tio.c_lflag &= ~ICANON;
  95.     tio.c_cc[VMIN] = 1;
  96.     tio.c_cc[VTIME] = 0;
  97.     tcsetattr(fd, TCSAFLUSH, &tio);
  98. #endif
  99.     /* Get random noise from keyboard strokes */
  100.     randbuf = (char *) PORT_Alloc(RAND_BUF_SIZE);
  101.     count = 0;
  102.     while (count < NUM_KEYSTROKES+1) {
  103. #ifdef XP_UNIX
  104. c = getc(stdin);
  105. #else
  106. c = getch();
  107. #endif
  108. RNG_GetNoise(&randbuf[1], sizeof(randbuf)-1);
  109. RNG_RandomUpdate(randbuf, sizeof(randbuf));
  110. if (c != randbuf[0]) {
  111.     randbuf[0] = c;
  112.     FPS "r|");
  113.     for (i=0; i<count/(NUM_KEYSTROKES/RAND_BUF_SIZE); i++) {
  114. FPS "*");
  115.     }
  116.     if (count%(NUM_KEYSTROKES/RAND_BUF_SIZE) == 1)
  117. FPS "/");
  118.     count++;
  119. }
  120.     }
  121.     free(randbuf); 
  122.     FPS "nn");
  123.     FPS "Finished.  Press enter to continue: ");
  124.     while (getc(stdin) != 'n')
  125. ;
  126.     FPS "n");
  127. #undef FPS
  128. #ifdef XP_UNIX
  129.     /* set back termio the way it was */
  130.     tio.c_lflag = orig_lflag;
  131.     tio.c_cc[VMIN] = orig_cc_min;
  132.     tio.c_cc[VTIME] = orig_cc_time;
  133.     tcsetattr(fd, TCSAFLUSH, &tio);
  134. #endif
  135. }
  136. static unsigned char P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
  137.      0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
  138.      0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
  139.      0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
  140.      0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
  141.      0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
  142.      0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
  143.      0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
  144.      0x91 };
  145. static unsigned char Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
  146.      0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
  147.      0x8e, 0xda, 0xce, 0x91, 0x5f };
  148. static unsigned char G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
  149.      0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
  150.      0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
  151.      0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
  152.      0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
  153.      0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
  154.      0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
  155.      0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
  156.      0x02 };
  157. static PQGParams default_pqg_params = {
  158.     NULL,
  159.     { 0, P, sizeof(P) },
  160.     { 0, Q, sizeof(Q) },
  161.     { 0, G, sizeof(G) }
  162. };
  163. static PQGParams *
  164. decode_pqg_params(char *str)
  165. {
  166.     char *buf;
  167.     unsigned int len;
  168.     PRArenaPool *arena;
  169.     PQGParams *params;
  170.     SECStatus status;
  171.  
  172.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  173.     if (arena == NULL)
  174.         return NULL;
  175.  
  176.     params = PORT_ArenaZAlloc(arena, sizeof(PQGParams));
  177.     if (params == NULL)
  178.         goto loser;
  179.     params->arena = arena;
  180.  
  181.     buf = (char *)ATOB_AsciiToData(str, &len);
  182.     if ((buf == NULL) || (len == 0))
  183.         goto loser;
  184.  
  185.     status = SEC_ASN1Decode(arena, params, SECKEY_PQGParamsTemplate, buf, len);
  186.     if (status != SECSuccess)
  187.         goto loser;
  188.  
  189.     return params;
  190.  
  191. loser:
  192.     if (arena != NULL)
  193.         PORT_FreeArena(arena, PR_FALSE);
  194.     return NULL;
  195. }
  196.  
  197. static int
  198. pqg_prime_bits(char *str)
  199. {
  200.     PQGParams *params = NULL;
  201.     int primeBits = 0, i;
  202.  
  203.     params = decode_pqg_params(str);
  204.     if (params == NULL)
  205.         goto done; /* lose */
  206.  
  207.     for (i = 0; params->prime.data[i] == 0; i++)
  208.         /* empty */;
  209. primeBits = (params->prime.len - i) * 8;
  210.  
  211. done:
  212.     if (params != NULL)
  213.         PQG_DestroyParams(params);
  214.     return primeBits;
  215. }
  216. static char *
  217. SECU_GetpqgString(char *filename)
  218. {
  219.     unsigned char phrase[400];
  220.     FILE *fh;
  221.     char *rv;
  222.     fh = fopen(filename,"r");
  223.     rv = fgets ((char*) phrase, sizeof(phrase), fh);
  224.     fclose(fh);
  225.     if (phrase[strlen(phrase)-1] == 'n')
  226. phrase[strlen(phrase)-1] = '';
  227.     if (rv) {
  228. return (char*) PORT_Strdup((char*)phrase);
  229.     }
  230.     fprintf(stderr,"pqg file contain no datan");
  231.     return NULL;
  232. }
  233. PQGParams*
  234. getpqgfromfile(int keyBits, char *pqgFile)
  235. {
  236.     char *end, *str, *pqgString;
  237.     int primeBits;
  238.     pqgString = SECU_GetpqgString(pqgFile);
  239.     if (pqgString)
  240. str = PORT_Strdup(pqgString);
  241.     else
  242. return NULL;
  243.     do {
  244. end = PORT_Strchr(str, ',');
  245. if (end)
  246.     *end = '';
  247. primeBits = pqg_prime_bits(str);
  248. if (keyBits == primeBits)
  249.     goto found_match;
  250. str = end + 1;
  251.     } while (end);
  252.     PORT_Free(pqgString);
  253.     PORT_Free(str);
  254.     return NULL;
  255. found_match:
  256.     PORT_Free(pqgString);
  257.     PORT_Free(str);
  258.     return decode_pqg_params(str);
  259. }
  260. SECKEYPrivateKey *
  261. CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size,
  262.     int publicExponent, char *noise, 
  263.     SECKEYPublicKey **pubkeyp, char *pqgFile,
  264.                             char *passFile)
  265. {
  266.     CK_MECHANISM_TYPE mechanism;
  267.     SECOidTag algtag;
  268.     PK11RSAGenParams rsaparams;
  269.     PQGParams *dsaparams = NULL;
  270.     void *params;
  271.     secuPWData pwdata = { PW_NONE, 0 };
  272.     /*
  273.      * Do some random-number initialization.
  274.      */
  275.     RNG_SystemInfoForRNG();
  276.     if (noise) {
  277.      RNG_FileForRNG(noise);
  278.     } else {
  279. UpdateRNG();
  280.     }
  281.     switch (keytype) {
  282.       case rsaKey:
  283. rsaparams.keySizeInBits = size;
  284. rsaparams.pe = publicExponent;
  285. mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
  286. algtag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
  287. params = &rsaparams;
  288. break;
  289.       case dsaKey:
  290. mechanism = CKM_DSA_KEY_PAIR_GEN;
  291. algtag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
  292. if (pqgFile) {
  293.     dsaparams = getpqgfromfile(size, pqgFile);
  294. } else {
  295.     dsaparams = &default_pqg_params;
  296. }
  297. params = dsaparams;
  298.       default:
  299. return NULL;
  300.     }
  301.     if (slot == NULL)
  302. return NULL;
  303.     if (passFile) {
  304. pwdata.source = PW_FROMFILE;
  305. pwdata.data = passFile;
  306.     }
  307.     if (PK11_Authenticate(slot, PR_TRUE, &pwdata) != SECSuccess)
  308. return NULL;
  309.     fprintf(stderr, "nn");
  310.     fprintf(stderr, "Generating key.  This may take a few moments...nn");
  311.     return PK11_GenerateKeyPair(slot, mechanism, params, pubkeyp,
  312. PR_TRUE /*isPerm*/, PR_TRUE /*isSensitive*/, 
  313. NULL /*wincx*/);
  314. }
  315. /*
  316.  * The following is all functionality moved over from keyutil, which may
  317.  * or may not become completely obsolete.  So, some of this stuff may
  318.  * end up being turned on from within certutil.  Some is probably not
  319.  * even feasible anymore (Add/Delete?).
  320.  */
  321. #ifdef LATER
  322. static SECStatus
  323. ListKeys(FILE *out)
  324. {
  325.     int rt;
  326.     rt = SECU_PrintKeyNames(handle, out);
  327.     if (rt) {
  328. SECU_PrintError(progName, "unable to list nicknames");
  329. return SECFailure;
  330.     }
  331.     return SECSuccess;
  332. }
  333. static SECStatus
  334. DumpPublicKey(char *nickname, FILE *out)
  335. {
  336.     SECKEYLowPrivateKey *privKey;
  337.     SECKEYLowPublicKey *publicKey;
  338.     /* check if key actually exists */
  339.     if (SECU_CheckKeyNameExists(handle, nickname) == PR_FALSE) {
  340. SECU_PrintError(progName, "the key "%s" does not exist", nickname);
  341. return SECFailure;
  342.     }
  343.     /* Read in key */
  344.     privKey = SECU_GetPrivateKey(handle, nickname);
  345.     if (!privKey) {
  346. return SECFailure;
  347.     }
  348.     publicKey = SECKEY_LowConvertToPublicKey(privKey);
  349.     /* Output public key (in the clear) */
  350.     switch(publicKey->keyType) {
  351.       case rsaKey:
  352. fprintf(out, "RSA Public-Key:n");
  353. SECU_PrintInteger(out, &publicKey->u.rsa.modulus, "modulus", 1);
  354. SECU_PrintInteger(out, &publicKey->u.rsa.publicExponent,
  355.   "publicExponent", 1);
  356. break;
  357.       case dsaKey:
  358. fprintf(out, "DSA Public-Key:n");
  359. SECU_PrintInteger(out, &publicKey->u.dsa.params.prime, "prime", 1);
  360. SECU_PrintInteger(out, &publicKey->u.dsa.params.subPrime,
  361.   "subPrime", 1);
  362. SECU_PrintInteger(out, &publicKey->u.dsa.params.base, "base", 1);
  363. SECU_PrintInteger(out, &publicKey->u.dsa.publicValue, "publicValue", 1);
  364. break;
  365.       default:
  366. fprintf(out, "unknown key typen");
  367. break;
  368.     }
  369.     return SECSuccess;
  370. }
  371. static SECStatus
  372. DumpPrivateKey(char *nickname, FILE *out)
  373. {
  374.     SECKEYLowPrivateKey *key;
  375.     /* check if key actually exists */
  376.     if (SECU_CheckKeyNameExists(handle, nickname) == PR_FALSE) {
  377. SECU_PrintError(progName, "the key "%s" does not exist", nickname);
  378. return SECFailure;
  379.     }
  380.     /* Read in key */
  381.     key = SECU_GetPrivateKey(handle, nickname);
  382.     if (!key) {
  383. SECU_PrintError(progName, "error retrieving key");
  384. return SECFailure;
  385.     }
  386.     switch(key->keyType) {
  387.       case rsaKey:
  388. fprintf(out, "RSA Private-Key:n");
  389. SECU_PrintInteger(out, &key->u.rsa.modulus, "modulus", 1);
  390. SECU_PrintInteger(out, &key->u.rsa.publicExponent, "publicExponent", 1);
  391. SECU_PrintInteger(out, &key->u.rsa.privateExponent,
  392.   "privateExponent", 1);
  393. SECU_PrintInteger(out, &key->u.rsa.prime[0], "prime[0]", 1);
  394. SECU_PrintInteger(out, &key->u.rsa.prime[1], "prime[1]", 1);
  395. SECU_PrintInteger(out, &key->u.rsa.primeExponent[0],
  396.   "primeExponent[0]", 1);
  397. SECU_PrintInteger(out, &key->u.rsa.primeExponent[1],
  398.   "primeExponent[1]", 1);
  399. SECU_PrintInteger(out, &key->u.rsa.coefficient, "coefficient", 1);
  400. break;
  401.       case dsaKey:
  402. fprintf(out, "DSA Private-Key:n");
  403. SECU_PrintInteger(out, &key->u.dsa.params.prime, "prime", 1);
  404. SECU_PrintInteger(out, &key->u.dsa.params.subPrime, "subPrime", 1);
  405. SECU_PrintInteger(out, &key->u.dsa.params.base, "base", 1);
  406. SECU_PrintInteger(out, &key->u.dsa.publicValue, "publicValue", 1);
  407. SECU_PrintInteger(out, &key->u.dsa.privateValue, "privateValue", 1);
  408. break;
  409.       default:
  410. fprintf(out, "unknown key typen");
  411. break;
  412.     }
  413.     return SECSuccess;
  414. }
  415. static SECStatus
  416. ChangePassword(void)
  417. {
  418.     SECStatus rv;
  419.     /* Write out database with a new password */
  420.     rv = SECU_ChangeKeyDBPassword(handle);
  421.     if (rv) {
  422. SECU_PrintError(progName, "unable to change key password");
  423.     }
  424.     return rv;
  425. }
  426. static SECStatus DeletePrivateKey (char *nickName)
  427. {
  428.     int rv;
  429.     rv = SECU_DeleteKeyByName (keyHandle, nickName);
  430.     if (rv != SECSuccess)
  431. fprintf(stderr, "%s: problem deleting private key (%s)n",
  432. progName, SECU_Strerror(PR_GetError()));
  433.     return (rv);
  434. }
  435. #endif /* LATER */