/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h>
#include <string.h>
#include "secutil.h"
#if defined (XP_UNIX)
#include <unistd.h>
#include <sys/time.h>
#include <termios.h>
#endif
#if defined (XP_WIN) ||
defined (XP_PC)
#include <time.h>
#include <conio.h>
#endif
#include "nspr.h"
#include "prtypes.h"
#include "prtime.h"
#include "prlong.h"
#include "pk11func.h"
#define NUM_KEYSTROKES
120
#define RAND_BUF_SIZE
60
#define ERROR_BREAK \
rv = SECFailure; \
break ;
const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
{ 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 }
};
/* returns 0 for success, -1 for failure (EOF encountered) */
static int
UpdateRNG(
void )
{
char randbuf[RAND_BUF_SIZE];
#ifdef XP_UNIX
int fd;
#endif
int c;
int rv =
0 ;
size_t count;
#ifdef XP_UNIX
cc_t orig_cc_min;
cc_t orig_cc_time;
tcflag_t orig_lflag;
struct termios tio;
#endif
char meter[] = {
"\r| |"
};
#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
"is full. DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!\n" );
FPS
"\n" );
FPS
"\n" );
FPS
"Continue typing until the progress meter is full:\n\n" );
FPS
"%s" , meter);
FPS
"\r|" );
#if defined (XP_UNIX)
/* turn off echo on stdin & return on 1 char instead of NL */
fd = fileno(stdin);
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);
#endif
/* Get random noise from keyboard strokes */
count =
0 ;
while (count <
sizeof randbuf) {
#if defined (XP_UNIX)
c = getc(stdin);
#else
c = getch();
#endif
if (c == EOF) {
rv = -
1 ;
break ;
}
randbuf[count] = c;
if (count ==
0 || c != randbuf[count -
1 ]) {
count++;
FPS
"*" );
}
}
PK11_RandomUpdate(randbuf,
sizeof randbuf);
memset(randbuf,
0 ,
sizeof randbuf);
FPS
"\n\n" );
FPS
"Finished. Press enter to continue: " );
while ((c = getc(stdin)) !=
'\n' && c != EOF)
;
if (c == EOF)
rv = -
1 ;
FPS
"\n" );
#undef FPS
#if defined (XP_UNIX)
/* 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);
#endif
return rv;
}
static const unsigned char P[] = {
0 ,
0 xc6,
0 x2a,
0 x47,
0 x73,
0 xea,
0 x78,
0 xfa,
0 x65,
0 x47,
0 x69,
0 x39,
0 x10,
0 x08,
0 x55,
0 x6a,
0 xdd,
0 xbf,
0 x77,
0 xe1,
0 x9a,
0 x69,
0 x73,
0 xba,
0 x66,
0 x37,
0 x08,
0 x93,
0 x9e,
0 xdb,
0 x5d,
0 x01,
0 x08,
0 xb8,
0 x3a,
0 x73,
0 xe9,
0 x85,
0 x5f,
0 xa7,
0 x2b,
0 x63,
0 x7f,
0 xd0,
0 xc6,
0 x4c,
0 xdc,
0 xfc,
0 x8b,
0 xa6,
0 x03,
0 xc9,
0 x9c,
0 x80,
0 x5e,
0 xec,
0 xc6,
0 x21,
0 x23,
0 xf7,
0 x8e,
0 xa4,
0 x7b,
0 x77,
0 x83,
0 x02,
0 x44,
0 xf8,
0 x05,
0 xd7,
0 x36,
0 x52,
0 x13,
0 x57,
0 x78,
0 x97,
0 xf3,
0 x7b,
0 xcf,
0 x1f,
0 xc9,
0 x2a,
0 xa4,
0 x71,
0 x9d,
0 xa8,
0 xd8,
0 x5d,
0 xc5,
0 x3b,
0 x64,
0 x3a,
0 x72,
0 x60,
0 x62,
0 xb0,
0 xb8,
0 xf3,
0 xb1,
0 xe7,
0 xb9,
0 x76,
0 xdf,
0 x74,
0 xbe,
0 x87,
0 x6a,
0 xd2,
0 xf1,
0 xa9,
0 x44,
0 x8b,
0 x63,
0 x76,
0 x4f,
0 x5d,
0 x21,
0 x63,
0 xb5,
0 x4f,
0 x3c,
0 x7b,
0 x61,
0 xb2,
0 xf3,
0 xea,
0 xc5,
0 xd8,
0 xef,
0 x30,
0 x50,
0 x59,
0 x33,
0 x61,
0 xc0,
0 xf3,
0 x6e,
0 x21,
0 xcf,
0 x15,
0 x35,
0 x4a,
0 x87,
0 x2b,
0 xc3,
0 xf6,
0 x5a,
0 x1f,
0 x24,
0 x22,
0 xc5,
0 xeb,
0 x47,
0 x34,
0 x4a,
0 x1b,
0 xb5,
0 x2e,
0 x71,
0 x52,
0 x8f,
0 x2d,
0 x7d,
0 xa9,
0 x96,
0 x8a,
0 x7c,
0 x61,
0 xdb,
0 xc0,
0 xdc,
0 xf1,
0 xca,
0 x28,
0 x69,
0 x1c,
0 x97,
0 xad,
0 xea,
0 x0d,
0 x9e,
0 x02,
0 xe6,
0 xe5,
0 x7d,
0 xad,
0 xe0,
0 x42,
0 x91,
0 x4d,
0 xfa,
0 xe2,
0 x81,
0 x16,
0 x2b,
0 xc2,
0 x96,
0 x3b,
0 x32,
0 x8c,
0 x20,
0 x69,
0 x8b,
0 x5b,
0 x17,
0 x3c,
0 xf9,
0 x13,
0 x6c,
0 x98,
0 x27,
0 x1c,
0 xca,
0 xcf,
0 x33,
0 xaa,
0 x93,
0 x21,
0 xaf,
0 x17,
0 x6e,
0 x5e,
0 x00,
0 x37,
0 xd9,
0 x34,
0 x8a,
0 x47,
0 xd2,
0 x1c,
0 x67,
0 x32,
0 x60,
0 xb6,
0 xc7,
0 xb0,
0 xfd,
0 x32,
0 x90,
0 x93,
0 x32,
0 xaa,
0 x11,
0 xba,
0 x23,
0 x19,
0 x39,
0 x6a,
0 x42,
0 x7c,
0 x1f,
0 xb7,
0 x28,
0 xdb,
0 x64,
0 xad,
0 xd9 };
static const unsigned char Q[] = {
0 ,
0 xe6,
0 xa3,
0 xc9,
0 xc6,
0 x51,
0 x92,
0 x8b,
0 xb3,
0 x98,
0 x8f,
0 x97,
0 xb8,
0 x31,
0 x0d,
0 x4a,
0 x03,
0 x1e,
0 xba,
0 x4e,
0 xe6,
0 xc8,
0 x90,
0 x98,
0 x1d,
0 x3a,
0 x95,
0 xf4,
0 xf1 };
static const unsigned char G[] = {
0 x70,
0 x32,
0 x58,
0 x5d,
0 xb3,
0 xbf,
0 xc3,
0 x62,
0 x63,
0 x0b,
0 xf8,
0 xa5,
0 xe1,
0 xed,
0 xeb,
0 x79,
0 xac,
0 x18,
0 x41,
0 x64,
0 xb3,
0 xda,
0 x4c,
0 xa7,
0 x92,
0 x63,
0 xb1,
0 x33,
0 x7c,
0 xcb,
0 x43,
0 xdc,
0 x1f,
0 x38,
0 x63,
0 x5e,
0 x0e,
0 x6d,
0 x45,
0 xd1,
0 xc9,
0 x67,
0 xf3,
0 xcf,
0 x3d,
0 x2d,
0 x16,
0 x4e,
0 x92,
0 x16,
0 x06,
0 x59,
0 x29,
0 x89,
0 x6f,
0 x54,
0 xff,
0 xc5,
0 x71,
0 xc8,
0 x3a,
0 x95,
0 x84,
0 xb6,
0 x7e,
0 x7b,
0 x1e,
0 x8b,
0 x47,
0 x9d,
0 x7a,
0 x3a,
0 x36,
0 x9b,
0 x70,
0 x2f,
0 xd1,
0 xbd,
0 xef,
0 xe8,
0 x3a,
0 x41,
0 xd4,
0 xf3,
0 x1f,
0 x81,
0 xc7,
0 x1f,
0 x96,
0 x7c,
0 x30,
0 xab,
0 xf4,
0 x7a,
0 xac,
0 x93,
0 xed,
0 x6f,
0 x67,
0 xb0,
0 xc9,
0 x5b,
0 xf3,
0 x83,
0 x9d,
0 xa0,
0 xd7,
0 xb9,
0 x01,
0 xed,
0 x28,
0 xae,
0 x1c,
0 x6e,
0 x2e,
0 x48,
0 xac,
0 x9f,
0 x7d,
0 xf3,
0 x00,
0 x48,
0 xee,
0 x0e,
0 xfb,
0 x7e,
0 x5e,
0 xcb,
0 xf5,
0 x39,
0 xd8,
0 x92,
0 x90,
0 x61,
0 x2d,
0 x1e,
0 x3c,
0 xd3,
0 x55,
0 x0d,
0 x34,
0 xd1,
0 x81,
0 xc4,
0 x89,
0 xea,
0 x94,
0 x2b,
0 x56,
0 x33,
0 x73,
0 x58,
0 x48,
0 xbf,
0 x23,
0 x72,
0 x19,
0 x5f,
0 x19,
0 xac,
0 xff,
0 x09,
0 xc8,
0 xcd,
0 xab,
0 x71,
0 xef,
0 x9e,
0 x20,
0 xfd,
0 xe3,
0 xb8,
0 x27,
0 x9e,
0 x65,
0 xb1,
0 x85,
0 xcd,
0 x88,
0 xfe,
0 xd4,
0 xd7,
0 x64,
0 x4d,
0 xe1,
0 xe8,
0 xa6,
0 xe5,
0 x96,
0 xc8,
0 x5d,
0 x9c,
0 xc6,
0 x70,
0 x6b,
0 xba,
0 x77,
0 x4e,
0 x90,
0 x4a,
0 xb0,
0 x96,
0 xc5,
0 xa0,
0 x9e,
0 x2c,
0 x01,
0 x03,
0 xbe,
0 xbd,
0 x71,
0 xba,
0 x0a,
0 x6f,
0 x9f,
0 xe5,
0 xdb,
0 x04,
0 x08,
0 xf2,
0 x9e,
0 x0f,
0 x1b,
0 xac,
0 xcd,
0 xbb,
0 x65,
0 x12,
0 xcf,
0 x77,
0 xc9,
0 x7d,
0 xbe,
0 x94,
0 x4b,
0 x9c,
0 x5b,
0 xde,
0 x0d,
0 xfa,
0 x57,
0 xdd,
0 x77,
0 x32,
0 xf0,
0 x5b,
0 x34,
0 xfd,
0 x19,
0 x95,
0 x33,
0 x60,
0 x87,
0 xe2,
0 xa2,
0 xf4
};
/* P, Q, G have been generated using the NSS makepqg utility:
* makepqg -l 2048 -g 224 -r
* (see also: bug 1170322)
*
* h: 1 (0x1)
* SEED:
* d2:0b:c5:63:1b:af:dc:36:b7:7c:b9:3e:36:01:a0:8f:
* 0e:be:d0:38:e4:78:d5:3c:7c:9e:a9:9a:d2:0b:c5:63:
* 1b:af:dc:36:b7:7c:b9:3e:36:01:a0:8f:0e:be:d0:38:
* e4:78:d5:3c:7c:9e:c7:70:d2:0b:c5:63:1b:af:dc:36:
* b7:7c:b9:3e:36:01:a0:8f:0e:be:d0:38:e4:78:d5:3c:
* 7c:9e:aa:3e
* g: 672
* counter: 0
*/
static const SECKEYPQGParams default_pqg_params = {
NULL,
{
0 , (
unsigned char *)P,
sizeof (P) },
{
0 , (
unsigned char *)Q,
sizeof (Q) },
{
0 , (
unsigned char *)G,
sizeof (G) }
};
static SECKEYPQGParams *
decode_pqg_params(
const char *str)
{
char *buf;
unsigned int len;
PLArenaPool *arena;
SECKEYPQGParams *params;
SECStatus status;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
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;
loser:
if (arena != NULL)
PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
void
CERTUTIL_DestroyParamsPQG(SECKEYPQGParams *params)
{
if (params->arena) {
PORT_FreeArena(params->arena, PR_FALSE);
}
}
static int
pqg_prime_bits(
const SECKEYPQGParams *params)
{
int primeBits =
0 ;
if (params != NULL) {
int i;
for (i =
0 ; params->prime.data[i] ==
0 ; i++) {
/* empty */;
}
primeBits = (params->prime.len - i) *
8 ;
}
return primeBits;
}
static char *
getPQGString(
const char *filename)
{
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) {
PR_Close(src);
fprintf(stderr,
"Failed to read PQG file %s\n" , filename);
return NULL;
}
numBytes = PR_Read(src, buf, info.size);
PR_Close(src);
if (numBytes != info.size) {
PORT_Free(buf);
fprintf(stderr,
"Failed to read PQG file %s\n" , filename);
PORT_SetError(SEC_ERROR_IO);
return NULL;
}
if (buf[numBytes -
1 ] ==
'\n' )
numBytes--;
if (buf[numBytes -
1 ] ==
'\r' )
numBytes--;
buf[numBytes] =
0 ;
return (
char *)buf;
}
static SECKEYPQGParams *
getpqgfromfile(
int keyBits,
const char *pqgFile)
{
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)
break ;
CERTUTIL_DestroyParamsPQG(params);
params = NULL;
}
if (end)
str = end +
1 ;
}
while (end);
PORT_Free(pqgString);
return params;
}
static SECStatus
CERTUTIL_FileForRNG(
const char *noise)
{
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 ) {
PK11_RandomUpdate(buf, count);
}
}
while (count >
0 );
PR_Close(fd);
return SECSuccess;
}
typedef struct curveNameTagPairStr {
char *curveName;
SECOidTag curveOidTag;
} CurveNameTagPair;
static CurveNameTagPair nameTagPair[] = {
{
"sect163k1" , SEC_OID_SECG_EC_SECT163K1 },
{
"nistk163" , SEC_OID_SECG_EC_SECT163K1 },
{
"sect163r1" , SEC_OID_SECG_EC_SECT163R1 },
{
"sect163r2" , SEC_OID_SECG_EC_SECT163R2 },
{
"nistb163" , SEC_OID_SECG_EC_SECT163R2 },
{
"sect193r1" , SEC_OID_SECG_EC_SECT193R1 },
{
"sect193r2" , SEC_OID_SECG_EC_SECT193R2 },
{
"sect233k1" , SEC_OID_SECG_EC_SECT233K1 },
{
"nistk233" , SEC_OID_SECG_EC_SECT233K1 },
{
"sect233r1" , SEC_OID_SECG_EC_SECT233R1 },
{
"nistb233" , SEC_OID_SECG_EC_SECT233R1 },
{
"sect239k1" , SEC_OID_SECG_EC_SECT239K1 },
{
"sect283k1" , SEC_OID_SECG_EC_SECT283K1 },
{
"nistk283" , SEC_OID_SECG_EC_SECT283K1 },
{
"sect283r1" , SEC_OID_SECG_EC_SECT283R1 },
{
"nistb283" , SEC_OID_SECG_EC_SECT283R1 },
{
"sect409k1" , SEC_OID_SECG_EC_SECT409K1 },
{
"nistk409" , SEC_OID_SECG_EC_SECT409K1 },
{
"sect409r1" , SEC_OID_SECG_EC_SECT409R1 },
{
"nistb409" , SEC_OID_SECG_EC_SECT409R1 },
{
"sect571k1" , SEC_OID_SECG_EC_SECT571K1 },
{
"nistk571" , SEC_OID_SECG_EC_SECT571K1 },
{
"sect571r1" , SEC_OID_SECG_EC_SECT571R1 },
{
"nistb571" , SEC_OID_SECG_EC_SECT571R1 },
{
"secp160k1" , SEC_OID_SECG_EC_SECP160K1 },
{
"secp160r1" , SEC_OID_SECG_EC_SECP160R1 },
{
"secp160r2" , SEC_OID_SECG_EC_SECP160R2 },
{
"secp192k1" , SEC_OID_SECG_EC_SECP192K1 },
{
"secp192r1" , SEC_OID_SECG_EC_SECP192R1 },
{
"nistp192" , SEC_OID_SECG_EC_SECP192R1 },
{
"secp224k1" , SEC_OID_SECG_EC_SECP224K1 },
{
"secp224r1" , SEC_OID_SECG_EC_SECP224R1 },
{
"nistp224" , SEC_OID_SECG_EC_SECP224R1 },
{
"secp256k1" , SEC_OID_SECG_EC_SECP256K1 },
{
"secp256r1" , SEC_OID_SECG_EC_SECP256R1 },
{
"nistp256" , SEC_OID_SECG_EC_SECP256R1 },
{
"secp384r1" , SEC_OID_SECG_EC_SECP384R1 },
{
"nistp384" , SEC_OID_SECG_EC_SECP384R1 },
{
"secp521r1" , SEC_OID_SECG_EC_SECP521R1 },
{
"nistp521" , SEC_OID_SECG_EC_SECP521R1 },
{
"prime192v1" , SEC_OID_ANSIX962_EC_PRIME192V1 },
{
"prime192v2" , SEC_OID_ANSIX962_EC_PRIME192V2 },
{
"prime192v3" , SEC_OID_ANSIX962_EC_PRIME192V3 },
{
"prime239v1" , SEC_OID_ANSIX962_EC_PRIME239V1 },
{
"prime239v2" , SEC_OID_ANSIX962_EC_PRIME239V2 },
{
"prime239v3" , SEC_OID_ANSIX962_EC_PRIME239V3 },
{
"c2pnb163v1" , SEC_OID_ANSIX962_EC_C2PNB163V1 },
{
"c2pnb163v2" , SEC_OID_ANSIX962_EC_C2PNB163V2 },
{
"c2pnb163v3" , SEC_OID_ANSIX962_EC_C2PNB163V3 },
{
"c2pnb176v1" , SEC_OID_ANSIX962_EC_C2PNB176V1 },
{
"c2tnb191v1" , SEC_OID_ANSIX962_EC_C2TNB191V1 },
{
"c2tnb191v2" , SEC_OID_ANSIX962_EC_C2TNB191V2 },
{
"c2tnb191v3" , SEC_OID_ANSIX962_EC_C2TNB191V3 },
{
"c2onb191v4" , SEC_OID_ANSIX962_EC_C2ONB191V4 },
{
"c2onb191v5" , SEC_OID_ANSIX962_EC_C2ONB191V5 },
{
"c2pnb208w1" , SEC_OID_ANSIX962_EC_C2PNB208W1 },
{
"c2tnb239v1" , SEC_OID_ANSIX962_EC_C2TNB239V1 },
{
"c2tnb239v2" , SEC_OID_ANSIX962_EC_C2TNB239V2 },
{
"c2tnb239v3" , SEC_OID_ANSIX962_EC_C2TNB239V3 },
{
"c2onb239v4" , SEC_OID_ANSIX962_EC_C2ONB239V4 },
{
"c2onb239v5" , SEC_OID_ANSIX962_EC_C2ONB239V5 },
{
"c2pnb272w1" , SEC_OID_ANSIX962_EC_C2PNB272W1 },
{
"c2pnb304w1" , SEC_OID_ANSIX962_EC_C2PNB304W1 },
{
"c2tnb359v1" , SEC_OID_ANSIX962_EC_C2TNB359V1 },
{
"c2pnb368w1" , SEC_OID_ANSIX962_EC_C2PNB368W1 },
{
"c2tnb431r1" , SEC_OID_ANSIX962_EC_C2TNB431R1 },
{
"secp112r1" , SEC_OID_SECG_EC_SECP112R1 },
{
"secp112r2" , SEC_OID_SECG_EC_SECP112R2 },
{
"secp128r1" , SEC_OID_SECG_EC_SECP128R1 },
{
"secp128r2" , SEC_OID_SECG_EC_SECP128R2 },
{
"sect113r1" , SEC_OID_SECG_EC_SECT113R1 },
{
"sect113r2" , SEC_OID_SECG_EC_SECT113R2 },
{
"sect131r1" , SEC_OID_SECG_EC_SECT131R1 },
{
"sect131r2" , SEC_OID_SECG_EC_SECT131R2 },
{
"curve25519" , SEC_OID_CURVE25519 },
};
static SECKEYECParams *
getECParams(
const char *curve)
{
SECKEYECParams *ecparams;
SECOidData *oidData = NULL;
SECOidTag curveOidTag = SEC_OID_UNKNOWN;
/* default */
int i, numCurves;
if (curve != NULL) {
numCurves =
sizeof (nameTagPair) /
sizeof (CurveNameTagPair);
for (i =
0 ; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
i++) {
if (PL_strcmp(curve, nameTagPair[i].curveName) ==
0 )
curveOidTag = nameTagPair[i].curveOidTag;
}
}
/* Return NULL if curve name is not recognized */
if ((curveOidTag == SEC_OID_UNKNOWN) ||
(oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
fprintf(stderr,
"Unrecognized elliptic curve %s\n" , curve);
return NULL;
}
ecparams = SECITEM_AllocItem(NULL, NULL, (
2 + oidData->oid.len));
/*
* ecparams->data needs to contain the ASN encoding of an object ID (OID)
* representing the named curve. The actual OID is in
* oidData->oid.data so we simply prepend 0x06 and OID length
*/
ecparams->data[
0 ] = SEC_ASN1_OBJECT_ID;
ecparams->data[
1 ] = oidData->oid.len;
memcpy(ecparams->data +
2 , oidData->oid.data, oidData->oid.len);
return ecparams;
}
SECKEYPrivateKey *
CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot,
int size,
int publicExponent,
const char *noise,
SECKEYPublicKey **pubkeyp,
const char *pqgFile,
PK11AttrFlags attrFlags, CK_FLAGS opFlagsOn,
CK_FLAGS opFlagsOff, secuPWData *pwdata)
{
CK_MECHANISM_TYPE mechanism;
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) {
PORT_SetError(PR_END_OF_FILE_ERROR);
return NULL;
}
}
switch (keytype) {
case rsaKey:
rsaparams.keySizeInBits = size;
rsaparams.pe = publicExponent;
mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
params = &rsaparams;
break ;
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;
}
break ;
case ecKey:
mechanism = CKM_EC_KEY_PAIR_GEN;
/* For EC keys, PQGFile determines EC parameters */
if ((params = (
void *)getECParams(pqgFile)) == NULL)
return NULL;
break ;
default :
return NULL;
}
fprintf(stderr,
"\n\n" );
fprintf(stderr,
"Generating key. This may take a few moments...\n\n" );
privKey = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubkeyp,
attrFlags, opFlagsOn, opFlagsOn | opFlagsOff,
pwdata
/*wincx*/);
/* free up the params */
switch (keytype) {
case dsaKey:
if (dsaparams)
CERTUTIL_DestroyParamsPQG(dsaparams);
break ;
case ecKey:
SECITEM_FreeItem((SECItem *)params, PR_TRUE);
break ;
default :
/* nothing to free */
break ;
}
return privKey;
}
Messung V0.5 in Prozent C=94 H=89 G=91
¤ Dauer der Verarbeitung: 0.34 Sekunden
(vorverarbeitet am 2026-06-06)
¤
*© Formatika GbR, Deutschland