Bug 599324, land NSPR_4_8_7_BETA1 and NSS_3_12_9_BETA2, a=blocking-2.0-beta8+

This commit is contained in:
Kai Engert 2010-12-09 12:04:11 +01:00
Родитель 06c5fc57d3
Коммит 184e8c1f20
55 изменённых файлов: 5764 добавлений и 1991 удалений

Просмотреть файл

@ -1 +1 @@
NSPR_HEAD_20101015 NSPR_4_8_7_BETA1

Просмотреть файл

@ -42,4 +42,3 @@
*/ */
#error "Do not include this header file." #error "Do not include this header file."

Просмотреть файл

@ -111,19 +111,19 @@ NSPR_API(PRInt32) PR_AtomicAdd(PRInt32 *ptr, PRInt32 val);
** interchangeably. ** interchangeably.
*/ */
#if defined(_WIN32) && !defined(_WIN32_WCE) && \ #if defined(_WIN32) && !defined(_WIN32_WCE) && \
defined(_MSC_VER) && (_MSC_VER >= 1310) (!defined(_MSC_VER) || (_MSC_VER >= 1310))
#ifdef _MSC_VER
#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)
#pragma intrinsic(_InterlockedExchange)
#pragma intrinsic(_InterlockedExchangeAdd)
#endif
long __cdecl _InterlockedIncrement(long volatile *Addend); long __cdecl _InterlockedIncrement(long volatile *Addend);
#pragma intrinsic(_InterlockedIncrement)
long __cdecl _InterlockedDecrement(long volatile *Addend); long __cdecl _InterlockedDecrement(long volatile *Addend);
#pragma intrinsic(_InterlockedDecrement)
long __cdecl _InterlockedExchange(long volatile *Target, long Value); long __cdecl _InterlockedExchange(long volatile *Target, long Value);
#pragma intrinsic(_InterlockedExchange)
long __cdecl _InterlockedExchangeAdd(long volatile *Addend, long Value); long __cdecl _InterlockedExchangeAdd(long volatile *Addend, long Value);
#pragma intrinsic(_InterlockedExchangeAdd)
#define PR_ATOMIC_INCREMENT(val) _InterlockedIncrement((long volatile *)(val)) #define PR_ATOMIC_INCREMENT(val) _InterlockedIncrement((long volatile *)(val))
#define PR_ATOMIC_DECREMENT(val) _InterlockedDecrement((long volatile *)(val)) #define PR_ATOMIC_DECREMENT(val) _InterlockedDecrement((long volatile *)(val))

Просмотреть файл

@ -566,9 +566,8 @@ PR_IMPLEMENT(void) PR_Abort(void)
PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln) PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln)
{ {
PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln); PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln);
#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
#endif fflush(stderr);
#ifdef WIN32 #ifdef WIN32
DebugBreak(); DebugBreak();
#endif #endif

Просмотреть файл

@ -87,7 +87,7 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
t->md.gcContext[0] = 0; /* context.Eax */ t->md.gcContext[0] = 0; /* context.Eax */
t->md.gcContext[1] = fiberData[0x2e]; /* context.Ebx */ t->md.gcContext[1] = fiberData[0x2e]; /* context.Ebx */
t->md.gcContext[2] = 0; /* context.Ecx */ t->md.gcContext[2] = 0; /* context.Ecx */
t->md.gcContext[2] = 0; /* context.Edx */ t->md.gcContext[3] = 0; /* context.Edx */
t->md.gcContext[4] = fiberData[0x2d]; /* context.Esi */ t->md.gcContext[4] = fiberData[0x2d]; /* context.Esi */
t->md.gcContext[5] = fiberData[0x2c]; /* context.Edi */ t->md.gcContext[5] = fiberData[0x2c]; /* context.Edi */
t->md.gcContext[6] = fiberData[0x36]; /* context.Esp */ t->md.gcContext[6] = fiberData[0x36]; /* context.Esp */

Просмотреть файл

@ -780,8 +780,28 @@ PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks)
static void _pt_thread_death(void *arg) static void _pt_thread_death(void *arg)
{ {
void *thred;
int rv;
_PT_PTHREAD_GETSPECIFIC(pt_book.key, thred);
if (NULL == thred)
{
/*
* Have PR_GetCurrentThread return the expected value to the
* destructors.
*/
rv = pthread_setspecific(pt_book.key, arg);
PR_ASSERT(0 == rv);
}
/* PR_TRUE for: call destructors */ /* PR_TRUE for: call destructors */
_pt_thread_death_internal(arg, PR_TRUE); _pt_thread_death_internal(arg, PR_TRUE);
if (NULL == thred)
{
rv = pthread_setspecific(pt_book.key, NULL);
PR_ASSERT(0 == rv);
}
} }
static void _pt_thread_death_internal(void *arg, PRBool callDestructors) static void _pt_thread_death_internal(void *arg, PRBool callDestructors)

Просмотреть файл

@ -42,3 +42,5 @@
*/ */
#error "Do not include this header file." #error "Do not include this header file."

Просмотреть файл

@ -1 +1 @@
NSS_3_12_8_RC0 NSS_3_12_9_BETA2

Просмотреть файл

@ -121,7 +121,7 @@ static void Usage()
#define PRINTUSAGE(subject, option, predicate) \ #define PRINTUSAGE(subject, option, predicate) \
fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate); fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
PRINTUSAGE(progName, "[-DEHSV]", "List available cipher modes"); /* XXX */ PRINTUSAGE(progName, "[-DEHSVR]", "List available cipher modes"); /* XXX */
fprintf(stderr, "\n"); fprintf(stderr, "\n");
PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer"); PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]"); PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
@ -218,6 +218,13 @@ static void Usage()
PRINTUSAGE("", "-g", "key size (in bytes)"); PRINTUSAGE("", "-g", "key size (in bytes)");
PRINTUSAGE("", "-u", "number of repetitions of context creation"); PRINTUSAGE("", "-u", "number of repetitions of context creation");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
PRINTUSAGE(progName, "-R [-g keysize] [-e exp]",
"Test the RSA populate key function");
PRINTUSAGE("", "", "[-r repetitions]");
PRINTUSAGE("", "-g", "key size (in bytes)");
PRINTUSAGE("", "-e", "rsa public exponent");
PRINTUSAGE("", "-r", "repetitions of the test");
fprintf(stderr, "\n");
PRINTUSAGE(progName, "-F", "Run the FIPS self-test"); PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test"); PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test");
@ -3137,6 +3144,192 @@ void ThreadExecTest(void *data)
cipherFinish(cipherInfo); cipherFinish(cipherInfo);
} }
static void rsaPrivKeyReset(RSAPrivateKey *tstKey)
{
PLArenaPool *arena;
tstKey->version.data = NULL;
tstKey->version.len = 0;
tstKey->modulus.data = NULL;
tstKey->modulus.len = 0;
tstKey->publicExponent.data = NULL;
tstKey->publicExponent.len = 0;
tstKey->privateExponent.data = NULL;
tstKey->privateExponent.len = 0;
tstKey->prime1.data = NULL;
tstKey->prime1.len = 0;
tstKey->prime2.data = NULL;
tstKey->prime2.len = 0;
tstKey->exponent1.data = NULL;
tstKey->exponent1.len = 0;
tstKey->exponent2.data = NULL;
tstKey->exponent2.len = 0;
tstKey->coefficient.data = NULL;
tstKey->coefficient.len = 0;
arena = tstKey->arena;
tstKey->arena = NULL;
if (arena) {
PORT_FreeArena(arena, PR_TRUE);
}
}
#define RSA_TEST_EQUAL(comp) \
if (!SECITEM_ItemsAreEqual(&(src->comp),&(dest->comp))) { \
fprintf(stderr, "key->" #comp " not equal"); \
if (src->comp.len != dest->comp.len) { \
fprintf(stderr, "src_len = %d, dest_len = %d", \
src->comp.len, dest->comp.len); \
} \
fprintf(stderr, "\n"); \
areEqual = PR_FALSE; \
}
static PRBool rsaPrivKeysAreEqual(RSAPrivateKey *src, RSAPrivateKey *dest)
{
PRBool areEqual = PR_TRUE;
RSA_TEST_EQUAL(modulus)
RSA_TEST_EQUAL(publicExponent)
RSA_TEST_EQUAL(privateExponent)
RSA_TEST_EQUAL(prime1)
RSA_TEST_EQUAL(prime2)
RSA_TEST_EQUAL(exponent1)
RSA_TEST_EQUAL(exponent2)
RSA_TEST_EQUAL(coefficient)
if (!areEqual) {
fprintf(stderr, "original key:\n");
dump_rsakey(src);
fprintf(stderr, "recreated key:\n");
dump_rsakey(dest);
}
return areEqual;
}
/*
* Test the RSA populate command to see that it can really build
* keys from it's components.
*/
static int doRSAPopulateTest(unsigned int keySize, unsigned long exponent)
{
RSAPrivateKey *srcKey;
RSAPrivateKey tstKey = { 0 };
SECItem expitem = { 0, 0, 0 };
SECStatus rv;
unsigned char pubExp[4];
int expLen = 0;
int failed = 0;
int i;
for (i=0; i < sizeof(unsigned long); i++) {
int shift = (sizeof(unsigned long) - i -1 ) * 8;
if (expLen || (exponent && ((unsigned long)0xffL << shift))) {
pubExp[expLen] = (unsigned char) ((exponent >> shift) & 0xff);
expLen++;
}
}
expitem.data = pubExp;
expitem.len = expLen;
srcKey = RSA_NewKey(keySize, &expitem);
if (srcKey == NULL) {
fprintf(stderr, "RSA Key Gen failed");
return -1;
}
/* test the basic case - most common, public exponent, modulus, prime */
tstKey.arena = NULL;
rsaPrivKeyReset(&tstKey);
tstKey.publicExponent = srcKey->publicExponent;
tstKey.modulus = srcKey->modulus;
tstKey.prime1 = srcKey->prime1;
rv = RSA_PopulatePrivateKey(&tstKey);
if (rv != SECSuccess) {
fprintf(stderr, "RSA Populate failed: pubExp mod p\n");
failed = 1;
} else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n");
failed = 1;
}
/* test the basic2 case, public exponent, modulus, prime2 */
rsaPrivKeyReset(&tstKey);
tstKey.publicExponent = srcKey->publicExponent;
tstKey.modulus = srcKey->modulus;
tstKey.prime1 = srcKey->prime2; /* test with q in the prime1 position */
rv = RSA_PopulatePrivateKey(&tstKey);
if (rv != SECSuccess) {
fprintf(stderr, "RSA Populate failed: pubExp mod q\n");
failed = 1;
} else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n");
failed = 1;
}
/* test the medium case, private exponent, prime1, prime2 */
rsaPrivKeyReset(&tstKey);
tstKey.privateExponent = srcKey->privateExponent;
tstKey.prime1 = srcKey->prime2; /* purposefully swap them to make */
tstKey.prime2 = srcKey->prime1; /* sure populated swaps them back */
rv = RSA_PopulatePrivateKey(&tstKey);
if (rv != SECSuccess) {
fprintf(stderr, "RSA Populate failed: privExp p q\n");
failed = 1;
} else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
fprintf(stderr, "RSA Populate key mismatch: privExp p q\n");
failed = 1;
}
/* test the advanced case, public exponent, private exponent, prime2 */
rsaPrivKeyReset(&tstKey);
tstKey.privateExponent = srcKey->privateExponent;
tstKey.publicExponent = srcKey->publicExponent;
tstKey.prime2 = srcKey->prime2; /* use q in the prime2 position */
rv = RSA_PopulatePrivateKey(&tstKey);
if (rv != SECSuccess) {
fprintf(stderr, "RSA Populate failed: pubExp privExp q\n");
fprintf(stderr, " - not fatal\n");
/* it's possible that we can't uniquely determine the original key
* from just the exponents and prime. Populate returns an error rather
* than return the wrong key. */
} else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
/* if we returned a key, it *must* be correct */
fprintf(stderr, "RSA Populate key mismatch: pubExp privExp q\n");
rv = RSA_PrivateKeyCheck(&tstKey);
failed = 1;
}
/* test the advanced case2, public exponent, private exponent, modulus */
rsaPrivKeyReset(&tstKey);
tstKey.privateExponent = srcKey->privateExponent;
tstKey.publicExponent = srcKey->publicExponent;
tstKey.modulus = srcKey->modulus;
rv = RSA_PopulatePrivateKey(&tstKey);
if (rv != SECSuccess) {
fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n");
failed = 1;
} else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n");
failed = 1;
}
return failed ? -1 : 0;
}
/* bltest commands */ /* bltest commands */
enum { enum {
cmd_Decrypt = 0, cmd_Decrypt = 0,
@ -3145,6 +3338,7 @@ enum {
cmd_Hash, cmd_Hash,
cmd_Nonce, cmd_Nonce,
cmd_Dump, cmd_Dump,
cmd_RSAPopulate,
cmd_Sign, cmd_Sign,
cmd_SelfTest, cmd_SelfTest,
cmd_Verify cmd_Verify
@ -3196,6 +3390,7 @@ static secuCommandFlag bltest_commands[] =
{ /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE }, { /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE },
{ /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE }, { /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE },
{ /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE }, { /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE },
{ /* cmd_RSAPopulate*/ 'R', PR_FALSE, 0, PR_FALSE },
{ /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE }, { /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE },
{ /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE }, { /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE },
{ /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE } { /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE }
@ -3309,6 +3504,7 @@ int main(int argc, char **argv)
goto print_usage; goto print_usage;
} }
if (bltest.commands[cmd_Sign].activated) if (bltest.commands[cmd_Sign].activated)
bltest.commands[cmd_Encrypt].activated = PR_TRUE; bltest.commands[cmd_Encrypt].activated = PR_TRUE;
if (bltest.commands[cmd_Verify].activated) if (bltest.commands[cmd_Verify].activated)
@ -3329,6 +3525,36 @@ int main(int argc, char **argv)
* Handle three simple cases first * Handle three simple cases first
*/ */
/* test the RSA_PopulatePrivateKey function */
if (bltest.commands[cmd_RSAPopulate].activated) {
unsigned int keySize = 1024;
unsigned long exponent = 65537;
int rounds = 1;
int ret;
if (bltest.options[opt_KeySize].activated) {
keySize = PORT_Atoi(bltest.options[opt_KeySize].arg);
}
if (bltest.options[opt_Rounds].activated) {
rounds = PORT_Atoi(bltest.options[opt_Rounds].arg);
}
if (bltest.options[opt_Exponent].activated) {
exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
}
for (i=0; i < rounds; i++) {
printf("Running RSA Populate test round %d\n",i);
ret = doRSAPopulateTest(keySize,exponent);
if (ret != 0) {
break;
}
}
if (ret != 0) {
fprintf(stderr,"RSA Populate test round %d: FAILED\n",i);
}
return ret;
}
/* Do BLAPI self-test */ /* Do BLAPI self-test */
if (bltest.commands[cmd_SelfTest].activated) { if (bltest.commands[cmd_SelfTest].activated) {
PRBool encrypt = PR_TRUE, decrypt = PR_TRUE; PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;

Просмотреть файл

@ -462,7 +462,7 @@ DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii)
} }
static SECStatus static SECStatus
listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot, listCerts(CERTCertDBHandle *handle, char *name, char *email, PK11SlotInfo *slot,
PRBool raw, PRBool ascii, PRFileDesc *outfile, void *pwarg) PRBool raw, PRBool ascii, PRFileDesc *outfile, void *pwarg)
{ {
SECItem data; SECItem data;
@ -530,8 +530,45 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
break; break;
} }
} }
} else if (email) {
CERTCertificate *the_cert;
certs = PK11_FindCertsFromEmailAddress(email, NULL);
if (!certs) {
SECU_PrintError(progName,
"Could not find certificates for email address: %s\n",
email);
return SECFailure;
}
for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs);
node = CERT_LIST_NEXT(node)) {
the_cert = node->cert;
/* now get the subjectList that matches this cert */
data.data = the_cert->derCert.data;
data.len = the_cert->derCert.len;
if (ascii) {
PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
BTOA_DataToAscii(data.data, data.len),
NS_CERT_TRAILER);
rv = SECSuccess;
} else if (raw) {
numBytes = PR_Write(outfile, data.data, data.len);
rv = SECSuccess;
if (numBytes != (PRInt32) data.len) {
SECU_PrintSystemError(progName, "error writing raw cert");
rv = SECFailure;
}
} else {
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate",
the_cert->trust);
if (rv != SECSuccess) {
SECU_PrintError(progName, "problem printing certificate");
}
}
if (rv != SECSuccess) {
break;
}
}
} else { } else {
certs = PK11_ListCertsInSlot(slot); certs = PK11_ListCertsInSlot(slot);
if (certs) { if (certs) {
for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs); for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs);
@ -553,12 +590,13 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
} }
static SECStatus static SECStatus
ListCerts(CERTCertDBHandle *handle, char *nickname, PK11SlotInfo *slot, ListCerts(CERTCertDBHandle *handle, char *nickname, char *email,
PRBool raw, PRBool ascii, PRFileDesc *outfile, secuPWData *pwdata) PK11SlotInfo *slot, PRBool raw, PRBool ascii, PRFileDesc *outfile,
secuPWData *pwdata)
{ {
SECStatus rv; SECStatus rv;
if (!ascii && !raw && !nickname) { if (!ascii && !raw && !nickname && !email) {
PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n", PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n",
"Certificate Nickname", "Trust Attributes", "", "Certificate Nickname", "Trust Attributes", "",
"SSL,S/MIME,JAR/XPI"); "SSL,S/MIME,JAR/XPI");
@ -569,15 +607,13 @@ ListCerts(CERTCertDBHandle *handle, char *nickname, PK11SlotInfo *slot,
list = PK11_ListCerts(PK11CertListAll, pwdata); list = PK11_ListCerts(PK11CertListAll, pwdata);
for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list);
node = CERT_LIST_NEXT(node)) node = CERT_LIST_NEXT(node)) {
{
SECU_PrintCertNickname(node, stdout); SECU_PrintCertNickname(node, stdout);
} }
CERT_DestroyCertList(list); CERT_DestroyCertList(list);
return SECSuccess; return SECSuccess;
} else { }
rv = listCerts(handle,nickname,slot,raw,ascii,outfile,pwdata); rv = listCerts(handle, nickname, email, slot, raw, ascii, outfile, pwdata);
}
return rv; return rv;
} }
@ -598,10 +634,8 @@ DeleteCert(CERTCertDBHandle *handle, char *name)
CERT_DestroyCertificate(cert); CERT_DestroyCertificate(cert);
if (rv) { if (rv) {
SECU_PrintError(progName, "unable to delete certificate"); SECU_PrintError(progName, "unable to delete certificate");
return SECFailure;
} }
return rv;
return SECSuccess;
} }
static SECStatus static SECStatus
@ -995,7 +1029,9 @@ Usage(char *progName)
progName); progName);
FPS "\t\t [-P targetDBPrefix] [--source-prefix sourceDBPrefix]\n"); FPS "\t\t [-P targetDBPrefix] [--source-prefix sourceDBPrefix]\n");
FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n"); FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n");
FPS "\t%s -L [-n cert-name] [-X] [-d certdir] [-P dbprefix] [-r] [-a]\n", progName); FPS "\t%s -L [-n cert-name] [--email email-address] [-X] [-r] [-a]\n",
progName);
FPS "\t\t [-d certdir] [-P dbprefix]\n");
FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n", FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
progName); progName);
FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName); FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName);
@ -1208,6 +1244,9 @@ static void LongUsage(char *progName)
"-L"); "-L");
FPS "%-20s Pretty print named cert (list all if unspecified)\n", FPS "%-20s Pretty print named cert (list all if unspecified)\n",
" -n cert-name"); " -n cert-name");
FPS "%-20s \n"
"%-20s Pretty print cert with email address (list all if unspecified)\n",
" --email email-address", "");
FPS "%-20s Cert database directory (default is ~/.netscape)\n", FPS "%-20s Cert database directory (default is ~/.netscape)\n",
" -d certdir"); " -d certdir");
FPS "%-20s Cert & Key database prefix\n", FPS "%-20s Cert & Key database prefix\n",
@ -1827,6 +1866,7 @@ enum certutilOpts {
opt_KeySize, opt_KeySize,
opt_TokenName, opt_TokenName,
opt_InputFile, opt_InputFile,
opt_Emailaddress,
opt_KeyIndex, opt_KeyIndex,
opt_KeyType, opt_KeyType,
opt_DetailedInfo, opt_DetailedInfo,
@ -1914,6 +1954,7 @@ secuCommandFlag options_init[] =
{ /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE }, { /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE },
{ /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE }, { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE },
{ /* opt_InputFile */ 'i', PR_TRUE, 0, PR_FALSE }, { /* opt_InputFile */ 'i', PR_TRUE, 0, PR_FALSE },
{ /* opt_Emailaddress */ 0, PR_TRUE, 0, PR_FALSE, "email" },
{ /* opt_KeyIndex */ 'j', PR_TRUE, 0, PR_FALSE }, { /* opt_KeyIndex */ 'j', PR_TRUE, 0, PR_FALSE },
{ /* opt_KeyType */ 'k', PR_TRUE, 0, PR_FALSE }, { /* opt_KeyType */ 'k', PR_TRUE, 0, PR_FALSE },
{ /* opt_DetailedInfo */ 'l', PR_FALSE, 0, PR_FALSE }, { /* opt_DetailedInfo */ 'l', PR_FALSE, 0, PR_FALSE },
@ -1991,6 +2032,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
char * upgradeTokenName = ""; char * upgradeTokenName = "";
KeyType keytype = rsaKey; KeyType keytype = rsaKey;
char * name = NULL; char * name = NULL;
char * email = NULL;
char * keysource = NULL; char * keysource = NULL;
SECOidTag hashAlgTag = SEC_OID_UNKNOWN; SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
int keysize = DEFAULT_KEY_BITS; int keysize = DEFAULT_KEY_BITS;
@ -2389,6 +2431,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
} }
name = SECU_GetOptionArg(&certutil, opt_Nickname); name = SECU_GetOptionArg(&certutil, opt_Nickname);
email = SECU_GetOptionArg(&certutil, opt_Emailaddress);
PK11_SetPasswordFunc(SECU_GetModulePassword); PK11_SetPasswordFunc(SECU_GetModulePassword);
@ -2579,7 +2622,7 @@ merge_fail:
/* List certs (-L) */ /* List certs (-L) */
if (certutil.commands[cmd_ListCerts].activated) { if (certutil.commands[cmd_ListCerts].activated) {
rv = ListCerts(certHandle, name, slot, rv = ListCerts(certHandle, name, email, slot,
certutil.options[opt_BinaryDER].activated, certutil.options[opt_BinaryDER].activated,
certutil.options[opt_ASCIIForIO].activated, certutil.options[opt_ASCIIForIO].activated,
(outFile) ? outFile : PR_STDOUT, &pwdata); (outFile) ? outFile : PR_STDOUT, &pwdata);

Просмотреть файл

@ -567,3 +567,9 @@ ER3(SEC_ERROR_EXPIRED_PASSWORD, (SEC_ERROR_BASE + 172),
ER3(SEC_ERROR_LOCKED_PASSWORD, (SEC_ERROR_BASE + 173), ER3(SEC_ERROR_LOCKED_PASSWORD, (SEC_ERROR_BASE + 173),
"The password is locked.") "The password is locked.")
ER3(SEC_ERROR_UNKNOWN_PKCS11_ERROR, (SEC_ERROR_BASE + 174),
"Unknown PKCS #11 error.")
ER3(SEC_ERROR_BAD_CRL_DP_URL, (SEC_ERROR_BASE + 175),
"Invalid or unsupported URL in CRL distribution point name.")

Просмотреть файл

@ -0,0 +1,86 @@
#! gmake
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1994-2000
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#MKPROG = purify -cache-dir=/u/mcgreer/pcache -best-effort \
# -always-use-cache-dir $(CC)
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include ../platlibs.mk
#EXTRA_SHARED_LIBS += \
# -L/usr/lib \
# -lposix4 \
# $(NULL)
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
include ../platrules.mk

Просмотреть файл

@ -0,0 +1,54 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Netscape security libraries.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1994-2000
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
CORE_DEPTH = ../../..
MODULE = nss
REQUIRES = seccmd dbm softoken
PROGRAM = rsapoptst
EXPORTS = \
$(NULL)
PRIVATE_EXPORTS = \
$(NULL)
CSRCS = \
rsapoptst.c \
$(NULL)

Просмотреть файл

@ -0,0 +1,550 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
* Portions created by the Red Hat, Inc. are Copyright (C) 2010
* the Red Hat, Inc.. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdio.h>
#include <stdlib.h>
#include "plgetopt.h"
#include "nss.h"
#include "secutil.h"
#include "pk11table.h"
#include "secmodt.h"
#include "pk11pub.h"
struct test_args {
char *arg;
int mask_value;
char *description;
};
static const struct test_args test_array[] = {
{"all", 0x1f, "run all the tests" },
{"e_n_p", 0x01, "public exponent, modulus, prime1"},
{"d_n_q", 0x02, "private exponent, modulus, prime2"},
{"d_p_q", 0x04, "private exponent, prime1, prime2"},
{"e_d_q", 0x08, "public exponent, private exponent, prime2"},
{"e_d_n", 0x10, "public exponent, private exponent, moduls"}
};
static const int test_array_size =
(sizeof(test_array)/sizeof(struct test_args));
static void Usage(char *progName)
{
int i;
#define PRINTUSAGE(subject, option, predicate) \
fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
fprintf(stderr, "%s [-k keysize] [-e exp] [-r rounds] [-t tests]\n "
"Test creating RSA private keys from Partial components\n",
progName);
PRINTUSAGE("", "-k", "key size (in bit)");
PRINTUSAGE("", "-e", "rsa public exponent");
PRINTUSAGE("", "-r", "number times to repeat the test");
PRINTUSAGE("", "-t", "run the specified tests");
for (i=0; i < test_array_size; i++) {
PRINTUSAGE("", test_array[i].arg, test_array[i].description);
}
fprintf(stderr,"\n");
}
/*
* Test the RSA populate command to see that it can really build
* keys from it's components.
*/
const static CK_ATTRIBUTE rsaTemplate[] = {
{CKA_CLASS, NULL, 0 },
{CKA_KEY_TYPE, NULL, 0 },
{CKA_TOKEN, NULL, 0 },
{CKA_SENSITIVE, NULL, 0 },
{CKA_PRIVATE, NULL, 0 },
{CKA_MODULUS, NULL, 0 },
{CKA_PUBLIC_EXPONENT, NULL, 0 },
{CKA_PRIVATE_EXPONENT, NULL, 0 },
{CKA_PRIME_1, NULL, 0 },
{CKA_PRIME_2, NULL, 0 },
{CKA_EXPONENT_1, NULL, 0 },
{CKA_EXPONENT_2, NULL, 0 },
{CKA_COEFFICIENT, NULL, 0 },
};
#define RSA_SIZE (sizeof(rsaTemplate))
#define RSA_ATTRIBUTES (sizeof(rsaTemplate)/sizeof(CK_ATTRIBUTE))
static void
resetTemplate(CK_ATTRIBUTE *attribute, int start, int end)
{
int i;
for (i=start; i < end; i++) {
if (attribute[i].pValue) {
PORT_Free(attribute[i].pValue);
}
attribute[i].pValue = NULL;
attribute[i].ulValueLen = 0;
}
}
static SECStatus
copyAttribute(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template,
int offset, CK_ATTRIBUTE_TYPE attrType)
{
SECItem attributeItem = {0, 0, 0};
SECStatus rv;
rv = PK11_ReadRawAttribute(objType, object, attrType, &attributeItem);
if (rv != SECSuccess) {
return rv;
}
template[offset].type = attrType;
template[offset].pValue = attributeItem.data;
template[offset].ulValueLen = attributeItem.len;
return SECSuccess;
}
static SECStatus
readKey(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template,
int start, int end)
{
int i;
SECStatus rv;
for (i=start; i < end; i++) {
rv = copyAttribute(objType, object, template, i, template[i].type);
if (rv != SECSuccess) {
goto fail;
}
}
return SECSuccess;
fail:
resetTemplate(template, start, i);
return rv;
}
#define ATTR_STRING(x) getNameFromAttribute(x)
void
dumpTemplate(CK_ATTRIBUTE *template, int start, int end)
{
int i,j;
for (i=0; i < end; i++) {
unsigned char cval;
CK_ULONG ulval;
unsigned char *cpval;
fprintf(stderr, "%s:", ATTR_STRING(template[i].type));
switch (template[i].ulValueLen) {
case 1:
cval =*(unsigned char *)template[i].pValue;
switch(cval) {
case 0: fprintf(stderr, " false"); break;
case 1: fprintf(stderr, " true"); break;
default:
fprintf(stderr, " %d (=0x%02x,'%c')",cval,cval,cval);
break;
}
break;
case sizeof(CK_ULONG):
ulval = *(CK_ULONG *)template[i].pValue;
fprintf(stderr," %ld (=0x%04lx)", ulval, ulval);
break;
default:
cpval = (unsigned char *)template[i].pValue;
for (j=0; j < template[i].ulValueLen; j++) {
if ((j % 16) == 0) fprintf(stderr, "\n ");
fprintf(stderr," %02x",cpval[j]);
}
break;
}
fprintf(stderr,"\n");
}
}
PRBool
rsaKeysAreEqual(PK11ObjectType srcType, void *src,
PK11ObjectType destType, void *dest)
{
CK_ATTRIBUTE srcTemplate[RSA_ATTRIBUTES];
CK_ATTRIBUTE destTemplate[RSA_ATTRIBUTES];
PRBool areEqual = PR_TRUE;
SECStatus rv;
int i;
memcpy(srcTemplate, rsaTemplate, RSA_SIZE);
memcpy(destTemplate, rsaTemplate, RSA_SIZE);
rv = readKey(srcType, src, srcTemplate, 0, RSA_ATTRIBUTES);
if (rv != SECSuccess) {
printf("Could read source key\n");
return PR_FALSE;
}
readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES);
if (rv != SECSuccess) {
printf("Could read dest key\n");
return PR_FALSE;
}
for (i=0; i < RSA_ATTRIBUTES; i++) {
if (srcTemplate[i].ulValueLen != destTemplate[i].ulValueLen) {
printf("key->%s not equal src_len = %ld, dest_len=%ld\n",
ATTR_STRING(srcTemplate[i].type),
srcTemplate[i].ulValueLen, destTemplate[i].ulValueLen);
areEqual = 0;
} else if (memcmp(srcTemplate[i].pValue, destTemplate[i].pValue,
destTemplate[i].ulValueLen) != 0) {
printf("key->%s not equal.\n", ATTR_STRING(srcTemplate[i].type));
areEqual = 0;
}
}
if (!areEqual) {
fprintf(stderr, "original key:\n");
dumpTemplate(srcTemplate,0, RSA_ATTRIBUTES);
fprintf(stderr, "created key:\n");
dumpTemplate(destTemplate,0, RSA_ATTRIBUTES);
}
return areEqual;
}
static int exp_exp_prime_fail_count = 0;
static int
doRSAPopulateTest(unsigned int keySize, unsigned long exponent,
int mask, void *pwarg)
{
SECKEYPrivateKey *rsaPrivKey;
SECKEYPublicKey *rsaPubKey;
PK11GenericObject *tstPrivKey;
CK_ATTRIBUTE tstTemplate[RSA_ATTRIBUTES];
int tstHeaderCount;
PK11SlotInfo *slot = NULL;
PK11RSAGenParams rsaParams;
CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY;
CK_KEY_TYPE key_type = CKK_RSA;
CK_BBOOL ck_false = CK_FALSE;
int failed = 0;
rsaParams.pe = exponent;
rsaParams.keySizeInBits = keySize;
slot = PK11_GetInternalSlot();
if (slot == NULL) {
fprintf(stderr, "Couldn't get the internal slot for the test \n");
return -1;
}
rsaPrivKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
&rsaParams, &rsaPubKey, PR_FALSE,
PR_FALSE, pwarg);
if (rsaPrivKey == NULL) {
fprintf(stderr, "RSA Key Gen failed");
PK11_FreeSlot(slot);
return -1;
}
memcpy(tstTemplate, rsaTemplate, RSA_SIZE);
tstTemplate[0].pValue = &obj_class;
tstTemplate[0].ulValueLen = sizeof(obj_class);
tstTemplate[1].pValue = &key_type;
tstTemplate[1].ulValueLen = sizeof(key_type);
tstTemplate[2].pValue = &ck_false;
tstTemplate[2].ulValueLen = sizeof(ck_false);
tstTemplate[3].pValue = &ck_false;
tstTemplate[3].ulValueLen = sizeof(ck_false);
tstTemplate[4].pValue = &ck_false;
tstTemplate[4].ulValueLen = sizeof(ck_false);
tstHeaderCount = 5;
if (mask & 1) {
printf("%s\n",test_array[1].description);
resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount, CKA_PUBLIC_EXPONENT);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+1, CKA_MODULUS);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+2, CKA_PRIME_1);
tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate,
tstHeaderCount+3, PR_FALSE);
if (tstPrivKey == NULL) {
fprintf(stderr, "RSA Populate failed: pubExp mod p\n");
failed = 1;
} else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey,
PK11_TypeGeneric, tstPrivKey)) {
fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n");
failed = 1;
}
if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey);
}
if (mask & 2) {
printf("%s\n",test_array[2].description);
/* test the basic2 case, public exponent, modulus, prime2 */
resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount, CKA_PUBLIC_EXPONENT);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+1, CKA_MODULUS);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+2, CKA_PRIME_2);
/* test with q in the prime1 position */
tstTemplate[tstHeaderCount+2].type = CKA_PRIME_1;
tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate,
tstHeaderCount+3, PR_FALSE);
if (tstPrivKey == NULL) {
fprintf(stderr, "RSA Populate failed: pubExp mod q\n");
failed = 1;
} else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey,
PK11_TypeGeneric, tstPrivKey)) {
fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n");
failed = 1;
}
if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey);
}
if (mask & 4) {
printf("%s\n",test_array[3].description);
/* test the medium case, private exponent, prime1, prime2 */
resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount, CKA_PRIVATE_EXPONENT);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+1, CKA_PRIME_1);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+2, CKA_PRIME_2);
/* test with p & q swapped. Underlying code should swap these back */
tstTemplate[tstHeaderCount+2].type = CKA_PRIME_1;
tstTemplate[tstHeaderCount+1].type = CKA_PRIME_2;
tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate,
tstHeaderCount+3, PR_FALSE);
if (tstPrivKey == NULL) {
fprintf(stderr, "RSA Populate failed: privExp p q\n");
failed = 1;
} else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey,
PK11_TypeGeneric, tstPrivKey)) {
fprintf(stderr, "RSA Populate key mismatch: privExp p q\n");
failed = 1;
}
if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey);
}
if (mask & 8) {
printf("%s\n",test_array[4].description);
/* test the advanced case, public exponent, private exponent, prime2 */
resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount, CKA_PRIVATE_EXPONENT);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+1, CKA_PUBLIC_EXPONENT);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+2, CKA_PRIME_2);
tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate,
tstHeaderCount+3, PR_FALSE);
if (tstPrivKey == NULL) {
fprintf(stderr, "RSA Populate failed: pubExp privExp q\n");
fprintf(stderr, " this is expected periodically. It means we\n");
fprintf(stderr, " had more than one key that meets the "
"specification\n");
exp_exp_prime_fail_count++;
} else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey,
PK11_TypeGeneric, tstPrivKey)) {
fprintf(stderr, "RSA Populate key mismatch: pubExp privExp q\n");
failed = 1;
}
if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey);
}
if (mask & 16) {
printf("%s\n",test_array[5].description);
/* test the advanced case2, public exponent, private exponent, modulus
*/
resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount, CKA_PRIVATE_EXPONENT);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+1, CKA_PUBLIC_EXPONENT);
copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate,
tstHeaderCount+2, CKA_MODULUS);
tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate,
tstHeaderCount+3, PR_FALSE);
if (tstPrivKey == NULL) {
fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n");
failed = 1;
} else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey,
PK11_TypeGeneric, tstPrivKey)) {
fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n");
failed = 1;
}
if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey);
}
PK11_FreeSlot(slot);
return failed ? -1 : 0;
}
/* populate options */
enum {
opt_Exponent = 0,
opt_KeySize,
opt_Repeat,
opt_Tests
};
static secuCommandFlag populate_options[] =
{
{ /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE },
{ /* opt_KeySize */ 'k', PR_TRUE, 0, PR_FALSE },
{ /* opt_Repeat */ 'r', PR_TRUE, 0, PR_FALSE },
{ /* opt_Tests */ 't', PR_TRUE, 0, PR_FALSE },
};
int
is_delimiter(char c)
{
if ((c=='+') || (c==',') || (c=='|')) {
return 1;
}
return 0;
}
int
parse_tests(char *test_string)
{
int mask = 0;
int i;
while (*test_string) {
if (is_delimiter(*test_string)) {
test_string++;
}
for (i=0; i < test_array_size; i++) {
char *arg = test_array[i].arg;
int len = strlen(arg);
if (strncmp(test_string,arg,len) == 0) {
test_string += len;
mask |= test_array[i].mask_value;
break;
}
}
if (i == test_array_size) {
break;
}
}
return mask;
}
int main(int argc, char **argv)
{
unsigned int keySize = 1024;
unsigned long exponent = 65537;
int i, repeat = 1, ret = 0;
SECStatus rv = SECFailure;
secuCommand populateArgs;
char *progName;
int mask = 0xff;
populateArgs.numCommands = 0;
populateArgs.numOptions = sizeof(populate_options) /
sizeof(secuCommandFlag);
populateArgs.commands = NULL;
populateArgs.options = populate_options;
progName = strrchr(argv[0], '/');
if (!progName)
progName = strrchr(argv[0], '\\');
progName = progName ? progName+1 : argv[0];
rv = NSS_NoDB_Init(NULL);
if (rv != SECSuccess) {
SECU_PrintPRandOSError(progName);
return -1;
}
rv = SECU_ParseCommandLine(argc, argv, progName, &populateArgs);
if (rv == SECFailure) {
fprintf(stderr, "%s: command line parsing error!\n", progName);
Usage(progName);
return -1;
}
rv = SECFailure;
if (populateArgs.options[opt_KeySize].activated) {
keySize = PORT_Atoi(populateArgs.options[opt_KeySize].arg);
}
if (populateArgs.options[opt_Repeat].activated) {
repeat = PORT_Atoi(populateArgs.options[opt_Repeat].arg);
}
if (populateArgs.options[opt_Exponent].activated) {
exponent = PORT_Atoi(populateArgs.options[opt_Exponent].arg);
}
if (populateArgs.options[opt_Tests].activated) {
char * test_string = populateArgs.options[opt_Tests].arg;
mask = PORT_Atoi(test_string);
if (mask == 0) {
mask = parse_tests(test_string);
}
if (mask == 0) {
Usage(progName);
return -1;
}
}
exp_exp_prime_fail_count = 0;
for (i=0; i < repeat; i++) {
printf("Running RSA Populate test run %d\n",i);
ret = doRSAPopulateTest(keySize, exponent, mask, NULL);
if (ret != 0) {
i++;
break;
}
}
if (ret != 0) {
fprintf(stderr,"RSA Populate test round %d: FAILED\n",i);
}
if (repeat > 1) {
printf(" pub priv prime test: %d failures out of %d runs (%f %%)\n",
exp_exp_prime_fail_count, i,
(((double)exp_exp_prime_fail_count) * 100.0)/(double) i);
}
return ret;
}

Просмотреть файл

@ -729,8 +729,7 @@ breakout:
/* Display validation results */ /* Display validation results */
if (secStatus != SECSuccess || log.count > 0) { if (secStatus != SECSuccess || log.count > 0) {
CERTVerifyLogNode *node = NULL; CERTVerifyLogNode *node = NULL;
PRIntn err = PR_GetError(); fprintf(stderr, "Chain is bad!\n");
fprintf(stderr, "Chain is bad, %d = %s\n", err, SECU_Strerror(err));
SECU_displayVerifyLog(stderr, &log, verbose); SECU_displayVerifyLog(stderr, &log, verbose);
/* Have cert refs in the log only in case of failure. /* Have cert refs in the log only in case of failure.

Просмотреть файл

@ -37,7 +37,7 @@
/* /*
* cert.h - public data structures and prototypes for the certificate library * cert.h - public data structures and prototypes for the certificate library
* *
* $Id: cert.h,v 1.80 2010/04/30 07:47:47 nelson%bolyard.com Exp $ * $Id: cert.h,v 1.80.2.1 2010/09/24 13:31:57 kaie%kuix.de Exp $
*/ */
#ifndef _CERT_H_ #ifndef _CERT_H_
@ -606,6 +606,16 @@ CERT_FindCertByEmailAddr(CERTCertDBHandle *handle, char *emailAddr);
CERTCertificate * CERTCertificate *
CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name); CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name);
/*
** Find a certificate in the database by a email address or nickname
** and require it to have the given usage.
** "name" is the email address or nickname to look up
*/
CERTCertificate *
CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
const char *name,
SECCertUsage lookingForUsage);
/* /*
** Find a certificate in the database by a digest of a subject public key ** Find a certificate in the database by a digest of a subject public key
** "spkDigest" is the digest to look up ** "spkDigest" is the digest to look up

Просмотреть файл

@ -614,19 +614,30 @@ CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
return STAN_GetCERTCertificateOrRelease(c); return STAN_GetCERTCertificateOrRelease(c);
} }
CERTCertificate * static CERTCertificate *
CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name) common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
char *name,
PRBool anyUsage,
SECCertUsage lookingForUsage)
{ {
NSSCryptoContext *cc; NSSCryptoContext *cc;
NSSCertificate *c, *ct; NSSCertificate *c, *ct;
CERTCertificate *cert; CERTCertificate *cert;
NSSUsage usage; NSSUsage usage;
CERTCertList *certlist;
if (NULL == name) { if (NULL == name) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
} }
usage.anyUsage = PR_TRUE;
usage.anyUsage = anyUsage;
if (!anyUsage) {
usage.nss3lookingForCA = PR_FALSE;
usage.nss3usage = lookingForUsage;
}
cc = STAN_GetDefaultCryptoContext(); cc = STAN_GetDefaultCryptoContext();
ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name,
NULL, &usage, NULL); NULL, &usage, NULL);
@ -638,7 +649,34 @@ CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
PORT_Free(lowercaseName); PORT_Free(lowercaseName);
} }
} }
cert = PK11_FindCertFromNickname(name, NULL);
if (anyUsage) {
cert = PK11_FindCertFromNickname(name, NULL);
}
else {
if (ct) {
/* Does ct really have the required usage? */
nssDecodedCert *dc;
dc = nssCertificate_GetDecoding(ct);
if (!dc->matchUsage(dc, &usage)) {
CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
ct = NULL;
}
}
certlist = PK11_FindCertsFromNickname(name, NULL);
if (certlist) {
SECStatus rv = CERT_FilterCertListByUsage(certlist,
lookingForUsage,
PR_FALSE);
if (SECSuccess == rv &&
!CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) {
cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert);
}
CERT_DestroyCertList(certlist);
}
}
if (cert) { if (cert) {
c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
CERT_DestroyCertificate(cert); CERT_DestroyCertificate(cert);
@ -651,6 +689,23 @@ CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
} }
CERTCertificate *
CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
{
return common_FindCertByNicknameOrEmailAddrForUsage(handle, name,
PR_TRUE, 0);
}
CERTCertificate *
CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
const char *name,
SECCertUsage lookingForUsage)
{
return common_FindCertByNicknameOrEmailAddrForUsage(handle, name,
PR_FALSE,
lookingForUsage);
}
static void static void
add_to_subject_list(CERTCertList *certList, CERTCertificate *cert, add_to_subject_list(CERTCertList *certList, CERTCertificate *cert,
PRBool validOnly, int64 sorttime) PRBool validOnly, int64 sorttime)

Просмотреть файл

@ -37,7 +37,7 @@
/* /*
* Interface to the OCSP implementation. * Interface to the OCSP implementation.
* *
* $Id: ocsp.h,v 1.17 2010/02/01 20:09:32 wtc%google.com Exp $ * $Id: ocsp.h,v 1.17.2.1 2010/09/27 21:22:20 wtc%google.com Exp $
*/ */
#ifndef _OCSP_H_ #ifndef _OCSP_H_
@ -476,9 +476,10 @@ CERT_RegisterAlternateOCSPAIAInfoCallBack(
/* /*
* FUNCTION: CERT_ParseURL * FUNCTION: CERT_ParseURL
* Parse the URI of a OCSP responder into hostname, port, and path. * Parse a URI into hostname, port, and path. The scheme in the URI must
* be "http".
* INPUTS: * INPUTS:
* const char *location * const char *url
* The URI to be parsed * The URI to be parsed
* OUTPUTS: * OUTPUTS:
* char *pHostname * char *pHostname
@ -490,9 +491,8 @@ CERT_RegisterAlternateOCSPAIAInfoCallBack(
* Pointer to store the path obtained from the URI. * Pointer to store the path obtained from the URI.
* This result should be freed (via PORT_Free) when no longer in use. * This result should be freed (via PORT_Free) when no longer in use.
* RETURN: * RETURN:
* Returns SECSuccess when parsing was successful. Anything else means * Returns SECSuccess when parsing was successful. Returns SECFailure when
* problems were encountered. * problems were encountered.
*
*/ */
extern SECStatus extern SECStatus
CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath); CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -77,8 +77,8 @@
* of the comment in the CK_VERSION type definition. * of the comment in the CK_VERSION type definition.
*/ */
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1 #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 80 #define NSS_BUILTINS_LIBRARY_VERSION_MINOR 81
#define NSS_BUILTINS_LIBRARY_VERSION "1.80" #define NSS_BUILTINS_LIBRARY_VERSION "1.81"
/* These version numbers detail the semantic changes to the ckfw engine. */ /* These version numbers detail the semantic changes to the ckfw engine. */
#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1

Просмотреть файл

@ -168,8 +168,8 @@ ifeq ($(CPU_ARCH),x86_64)
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
# DEFINES += -DMPI_AMD64_ADD # DEFINES += -DMPI_AMD64_ADD
# comment the next two lines to turn off intel HW accelleration # comment the next two lines to turn off intel HW accelleration
# DEFINES += -DUSE_HW_AES DEFINES += -DUSE_HW_AES
# ASFILES += intel-aes.s ASFILES += intel-aes.s
MPI_SRCS += mpi_amd64.c mp_comba.c MPI_SRCS += mpi_amd64.c mp_comba.c
endif endif
ifeq ($(CPU_ARCH),x86) ifeq ($(CPU_ARCH),x86)
@ -415,8 +415,8 @@ else
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
# comment the next two lines to turn off intel HW accelleration # comment the next two lines to turn off intel HW accelleration
# DEFINES += -DUSE_HW_AES DEFINES += -DUSE_HW_AES
# ASFILES += intel-aes.s ASFILES += intel-aes.s
MPI_SRCS += mpi_amd64.c MPI_SRCS += mpi_amd64.c
else else
# Solaris x86 # Solaris x86

Просмотреть файл

@ -37,7 +37,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: blapi.h,v 1.33 2009/03/29 03:45:32 wtc%google.com Exp $ */ /* $Id: blapi.h,v 1.33.22.2 2010/12/04 18:59:01 rrelyea%redhat.com Exp $ */
#ifndef _BLAPI_H_ #ifndef _BLAPI_H_
#define _BLAPI_H_ #define _BLAPI_H_
@ -98,11 +98,58 @@ extern SECStatus RSA_PrivateKeyOpDoubleChecked(RSAPrivateKey * key,
*/ */
extern SECStatus RSA_PrivateKeyCheck(RSAPrivateKey *key); extern SECStatus RSA_PrivateKeyCheck(RSAPrivateKey *key);
/*
** Given only minimal private key parameters, fill in the rest of the
** parameters.
**
**
** All the entries, including those supplied by the caller, will be
** overwritten with data alocated out of the arena.
**
** If no arena is supplied, one will be created.
**
** The following fields must be supplied in order for this function
** to succeed:
** one of either publicExponent or privateExponent
** two more of the following 5 parameters (not counting the above).
** modulus (n)
** prime1 (p)
** prime2 (q)
** publicExponent (e)
** privateExponent (d)
**
** NOTE: if only the publicExponent, privateExponent, and one prime is given,
** then there may be more than one RSA key that matches that combination. If
** we find 2 possible valid keys that meet this criteria, we return an error.
** If we return the wrong key, and the original modulus is compared to the
** new modulus, both can be factored by calculateing gcd(n_old,n_new) to get
** the common prime.
**
** NOTE: in some cases the publicExponent must be less than 2^23 for this
** function to work correctly. (The case where we have only one of: modulus
** prime1 and prime2).
**
** All parameters will be replaced in the key structure with new parameters
** allocated out of the arena. There is no attempt to free the old structures.
** prime1 will always be greater than prime2 (even if the caller supplies the
** smaller prime as prime1 or the larger prime as prime2). The parameters are
** not overwritten on failure.
**
** While the remaining Chinese remainder theorem parameters (dp,dp, and qinv)
** can also be used in reconstructing the private key, they are currently
** ignored in this implementation.
*/
extern SECStatus RSA_PopulatePrivateKey(RSAPrivateKey *key);
/******************************************************************** /********************************************************************
** DSA signing algorithm ** DSA signing algorithm
*/ */
/* Generate a new random value within the interval [2, q-1].
*/
extern SECStatus DSA_NewRandom(PLArenaPool * arena, const SECItem * q,
SECItem * random);
/* /*
** Generate and return a new DSA public and private key pair, ** Generate and return a new DSA public and private key pair,
** both of which are encoded into a single DSAPrivateKey struct. ** both of which are encoded into a single DSAPrivateKey struct.
@ -193,6 +240,72 @@ extern SECStatus KEA_Derive(SECItem *prime,
*/ */
extern PRBool KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime); extern PRBool KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime);
/****************************************
* J-PAKE key transport
*/
/* Given gx == g^x, create a Schnorr zero-knowledge proof for the value x
* using the specified hash algorithm and signer ID. The signature is
* returned in the values gv and r. testRandom must be NULL for a PRNG
* generated random committment to be used in the sigature. When testRandom
* is non-NULL, that value must contain a value in the subgroup q; that
* value will be used instead of a PRNG-generated committment in order to
* facilitate known-answer tests.
*
* If gxIn is non-NULL then it must contain a pre-computed value of g^x that
* will be used by the function; in this case, the gxOut parameter must be NULL.
* If the gxIn parameter is NULL then gxOut must be non-NULL; in this case
* gxOut will contain the value g^x on output.
*
* gx (if not supplied by the caller), gv, and r will be allocated in the arena.
* The arena is *not* optional so do not pass NULL for the arena parameter.
* The arena should be zeroed when it is freed.
*/
SECStatus
JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
const SECItem * signerID, const SECItem * x,
const SECItem * testRandom, const SECItem * gxIn, SECItem * gxOut,
SECItem * gv, SECItem * r);
/* Given gx == g^x, verify the Schnorr zero-knowledge proof (gv, r) for the
* value x using the specified hash algorithm and signer ID.
*
* The arena is *not* optional so do not pass NULL for the arena parameter.
*/
SECStatus
JPAKE_Verify(PRArenaPool * arena, const PQGParams * pqg,
HASH_HashType hashType, const SECItem * signerID,
const SECItem * peerID, const SECItem * gx,
const SECItem * gv, const SECItem * r);
/* Call before round 2 with x2, s, and x2s all non-NULL. This will calculate
* base = g^(x1+x3+x4) (mod p) and x2s = x2*s (mod q). The values to send in
* round 2 (A and the proof of knowledge of x2s) can then be calculated with
* JPAKE_Sign using pqg->base = base and x = x2s.
*
* Call after round 2 with x2, s, and x2s all NULL, and passing (gx1, gx2, gx3)
* instead of (gx1, gx3, gx4). This will calculate base = g^(x1+x2+x3). Then call
* JPAKE_Verify with pqg->base = base and then JPAKE_Final.
*
* base and x2s will be allocated in the arena. The arena is *not* optional so
* do not pass NULL for the arena parameter. The arena should be zeroed when it
* is freed.
*/
SECStatus
JPAKE_Round2(PLArenaPool * arena, const SECItem * p, const SECItem *q,
const SECItem * gx1, const SECItem * gx3, const SECItem * gx4,
SECItem * base, const SECItem * x2, const SECItem * s, SECItem * x2s);
/* K = (B/g^(x2*x4*s))^x2 (mod p)
*
* K will be allocated in the arena. The arena is *not* optional so do not pass
* NULL for the arena parameter. The arena should be zeroed when it is freed.
*/
SECStatus
JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem *q,
const SECItem * x2, const SECItem * gx4, const SECItem * x2s,
const SECItem * B, SECItem * K);
/****************************************************** /******************************************************
** Elliptic Curve algorithms ** Elliptic Curve algorithms
*/ */

Просмотреть файл

@ -35,7 +35,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: dsa.c,v 1.20 2009/03/29 16:51:58 wtc%google.com Exp $ */ /* $Id: dsa.c,v 1.20.22.1 2010/12/04 18:59:01 rrelyea%redhat.com Exp $ */
#ifdef FREEBL_NO_DEPEND #ifdef FREEBL_NO_DEPEND
#include "stubs.h" #include "stubs.h"
@ -56,21 +56,17 @@
/* XXX to be replaced by define in blapit.h */ /* XXX to be replaced by define in blapit.h */
#define NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE 2048 #define NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE 2048
#define FIPS_DSA_Q 160
#define QSIZE (FIPS_DSA_Q / PR_BITS_PER_BYTE)
/* /*
* FIPS 186-2 requires result from random output to be reduced mod q when * FIPS 186-2 requires result from random output to be reduced mod q when
* generating random numbers for DSA. * generating random numbers for DSA.
* *
* Input: w, 2*QSIZE bytes * Input: w, 2*qLen bytes
* q, DSA_SUBPRIME_LEN bytes * q, qLen bytes
* Output: xj, DSA_SUBPRIME_LEN bytes * Output: xj, qLen bytes
*/ */
SECStatus static SECStatus
FIPS186Change_ReduceModQForDSA(const PRUint8 *w, fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
const PRUint8 *q, unsigned int qLen, PRUint8 * xj)
PRUint8 *xj)
{ {
mp_int W, Q, Xj; mp_int W, Q, Xj;
mp_err err; mp_err err;
@ -86,15 +82,16 @@ FIPS186Change_ReduceModQForDSA(const PRUint8 *w,
/* /*
* Convert input arguments into MPI integers. * Convert input arguments into MPI integers.
*/ */
CHECK_MPI_OK( mp_read_unsigned_octets(&W, w, 2*QSIZE) ); CHECK_MPI_OK( mp_read_unsigned_octets(&W, w, 2*qLen) );
CHECK_MPI_OK( mp_read_unsigned_octets(&Q, q, DSA_SUBPRIME_LEN) ); CHECK_MPI_OK( mp_read_unsigned_octets(&Q, q, qLen) );
/* /*
* Algorithm 1 of FIPS 186-2 Change Notice 1, Step 3.3 * Algorithm 1 of FIPS 186-2 Change Notice 1, Step 3.3
* *
* xj = (w0 || w1) mod q * xj = (w0 || w1) mod q
*/ */
CHECK_MPI_OK( mp_mod(&W, &Q, &Xj) ); CHECK_MPI_OK( mp_mod(&W, &Q, &Xj) );
CHECK_MPI_OK( mp_to_fixlen_octets(&Xj, xj, DSA_SUBPRIME_LEN) ); CHECK_MPI_OK( mp_to_fixlen_octets(&Xj, xj, qLen) );
cleanup: cleanup:
mp_clear(&W); mp_clear(&W);
mp_clear(&Q); mp_clear(&Q);
@ -106,6 +103,17 @@ cleanup:
return rv; return rv;
} }
/*
* FIPS 186-2 requires result from random output to be reduced mod q when
* generating random numbers for DSA.
*/
SECStatus
FIPS186Change_ReduceModQForDSA(const unsigned char *w,
const unsigned char *q,
unsigned char *xj) {
return fips186Change_ReduceModQForDSA(w, q, DSA_SUBPRIME_LEN, xj);
}
/* /*
* The core of Algorithm 1 of FIPS 186-2 Change Notice 1. * The core of Algorithm 1 of FIPS 186-2 Change Notice 1.
* *
@ -137,24 +145,36 @@ FIPS186Change_GenerateX(PRUint8 *XKEY, const PRUint8 *XSEEDj,
** object. In DSA mode, so there is a q. ** object. In DSA mode, so there is a q.
*/ */
static SECStatus static SECStatus
dsa_GenerateGlobalRandomBytes(void *dest, size_t len, const PRUint8 *q) dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
unsigned int * destLen, unsigned int maxDestLen)
{ {
SECStatus rv; SECStatus rv;
PRUint8 w[2*QSIZE]; SECItem w;
const PRUint8 * q = qItem->data;
unsigned int qLen = qItem->len;
PORT_Assert(q && len == DSA_SUBPRIME_LEN);
if (len != DSA_SUBPRIME_LEN) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
if (*q == 0) { if (*q == 0) {
++q; ++q;
--qLen;
} }
rv = RNG_GenerateGlobalRandomBytes(w, 2*QSIZE); if (maxDestLen < qLen) {
if (rv != SECSuccess) { /* This condition can occur when DSA_SignDigest is passed a group
return rv; with a subprime that is larger than DSA_SUBPRIME_LEN. */
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
} }
FIPS186Change_ReduceModQForDSA(w, q, (PRUint8 *)dest); w.data = NULL; /* otherwise SECITEM_AllocItem asserts */
if (!SECITEM_AllocItem(NULL, &w, 2*qLen)) {
return SECFailure;
}
*destLen = qLen;
rv = RNG_GenerateGlobalRandomBytes(w.data, w.len);
if (rv == SECSuccess) {
rv = fips186Change_ReduceModQForDSA(w.data, q, qLen, dest);
}
SECITEM_FreeItem(&w, PR_FALSE);
return rv; return rv;
} }
@ -163,9 +183,9 @@ static void translate_mpi_error(mp_err err)
MP_TO_SEC_ERROR(err); MP_TO_SEC_ERROR(err);
} }
SECStatus static SECStatus
dsa_NewKey(const PQGParams *params, DSAPrivateKey **privKey, dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
const unsigned char *xb) DSAPrivateKey **privKey)
{ {
mp_int p, g; mp_int p, g;
mp_int x, y; mp_int x, y;
@ -173,7 +193,7 @@ dsa_NewKey(const PQGParams *params, DSAPrivateKey **privKey,
PRArenaPool *arena; PRArenaPool *arena;
DSAPrivateKey *key; DSAPrivateKey *key;
/* Check args. */ /* Check args. */
if (!params || !privKey) { if (!params || !privKey || !seed || !seed->data) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure; return SECFailure;
} }
@ -208,10 +228,10 @@ dsa_NewKey(const PQGParams *params, DSAPrivateKey **privKey,
/* Convert stored p, g, and received x into MPI integers. */ /* Convert stored p, g, and received x into MPI integers. */
SECITEM_TO_MPINT(params->prime, &p); SECITEM_TO_MPINT(params->prime, &p);
SECITEM_TO_MPINT(params->base, &g); SECITEM_TO_MPINT(params->base, &g);
OCTETS_TO_MPINT(xb, &x, DSA_SUBPRIME_LEN); OCTETS_TO_MPINT(seed->data, &x, seed->len);
/* Store x in private key */ /* Store x in private key */
SECITEM_AllocItem(arena, &key->privateValue, DSA_SUBPRIME_LEN); SECITEM_AllocItem(arena, &key->privateValue, seed->len);
memcpy(key->privateValue.data, xb, DSA_SUBPRIME_LEN); PORT_Memcpy(key->privateValue.data, seed->data, seed->len);
/* Compute public key y = g**x mod p */ /* Compute public key y = g**x mod p */
CHECK_MPI_OK( mp_exptmod(&g, &x, &p, &y) ); CHECK_MPI_OK( mp_exptmod(&g, &x, &p, &y) );
/* Store y in public key */ /* Store y in public key */
@ -232,6 +252,53 @@ cleanup:
return SECSuccess; return SECSuccess;
} }
SECStatus
DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
{
int retries = 10;
unsigned int i;
PRBool good;
if (q == NULL || q->data == NULL || q->len == 0 ||
(q->data[0] == 0 && q->len == 1)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (!SECITEM_AllocItem(arena, seed, q->len)) {
return SECFailure;
}
do {
/* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
if (dsa_GenerateGlobalRandomBytes(q, seed->data, &seed->len,
seed->len)) {
goto loser;
}
/* Disallow values of 0 and 1 for x. */
good = PR_FALSE;
for (i = 0; i < seed->len-1; i++) {
if (seed->data[i] != 0) {
good = PR_TRUE;
break;
}
}
if (!good && seed->data[i] > 1) {
good = PR_TRUE;
}
} while (!good && --retries > 0);
if (!good) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
loser: if (arena != NULL) {
SECITEM_FreeItem(seed, PR_FALSE);
}
return SECFailure;
}
return SECSuccess;
}
/* /*
** Generate and return a new DSA public and private key pair, ** Generate and return a new DSA public and private key pair,
** both of which are encoded into a single DSAPrivateKey struct. ** both of which are encoded into a single DSAPrivateKey struct.
@ -241,37 +308,21 @@ cleanup:
SECStatus SECStatus
DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey) DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
{ {
SECItem seed;
SECStatus rv; SECStatus rv;
unsigned char seed[DSA_SUBPRIME_LEN];
int retries = 10;
int i;
PRBool good;
do { seed.data = NULL;
/* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
if (dsa_GenerateGlobalRandomBytes(seed, DSA_SUBPRIME_LEN,
params->subPrime.data))
return SECFailure;
/* Disallow values of 0 and 1 for x. */
good = PR_FALSE;
for (i = 0; i < DSA_SUBPRIME_LEN-1; i++) {
if (seed[i] != 0) {
good = PR_TRUE;
break;
}
}
if (!good && seed[i] > 1) {
good = PR_TRUE;
}
} while (!good && --retries > 0);
if (!good) { rv = DSA_NewRandom(NULL, &params->subPrime, &seed);
PORT_SetError(SEC_ERROR_NEED_RANDOM); if (rv == SECSuccess) {
return SECFailure; if (seed.len != DSA_SUBPRIME_LEN) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
} else {
rv = dsa_NewKeyExtended(params, &seed, privKey);
}
} }
SECITEM_FreeItem(&seed, PR_FALSE);
/* Generate a new DSA key using random seed. */
rv = dsa_NewKey(params, privKey, seed);
return rv; return rv;
} }
@ -281,9 +332,11 @@ DSA_NewKeyFromSeed(const PQGParams *params,
const unsigned char *seed, const unsigned char *seed,
DSAPrivateKey **privKey) DSAPrivateKey **privKey)
{ {
SECStatus rv; /* TODO: check Q size */
rv = dsa_NewKey(params, privKey, seed); SECItem seedItem;
return rv; seedItem.data = (unsigned char*) seed;
seedItem.len = DSA_SUBPRIME_LEN;
return dsa_NewKeyExtended(params, &seedItem, privKey);
} }
static SECStatus static SECStatus
@ -393,18 +446,24 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
SECStatus rv; SECStatus rv;
int retries = 10; int retries = 10;
unsigned char kSeed[DSA_SUBPRIME_LEN]; unsigned char kSeed[DSA_SUBPRIME_LEN];
int i; unsigned int kSeedLen = 0;
unsigned int i;
PRBool good; PRBool good;
PORT_SetError(0); PORT_SetError(0);
do { do {
rv = dsa_GenerateGlobalRandomBytes(kSeed, DSA_SUBPRIME_LEN, rv = dsa_GenerateGlobalRandomBytes(&key->params.subPrime,
key->params.subPrime.data); kSeed, &kSeedLen, sizeof kSeed);
if (rv != SECSuccess) if (rv != SECSuccess)
break; break;
if (kSeedLen != DSA_SUBPRIME_LEN) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
break;
}
/* Disallow a value of 0 for k. */ /* Disallow a value of 0 for k. */
good = PR_FALSE; good = PR_FALSE;
for (i = 0; i < DSA_SUBPRIME_LEN; i++) { for (i = 0; i < kSeedLen; i++) {
if (kSeed[i] != 0) { if (kSeed[i] != 0) {
good = PR_TRUE; good = PR_TRUE;
break; break;

Просмотреть файл

@ -438,22 +438,18 @@ intel_aes_encrypt_cbc_128:
.globl intel_aes_decrypt_cbc_128 .globl intel_aes_decrypt_cbc_128
.align 16 .align 16
intel_aes_decrypt_cbc_128: intel_aes_decrypt_cbc_128:
// leaq IV_OFFSET(%rdi), %rdx leaq 16(%rdi), %rdx /* iv */
// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi leaq 48(%rdi), %rdi /* expanded key */
leaq 16(%rdi), %rdx
leaq 48(%rdi), %rdi
movdqu (%rdx), %xmm0 movdqu (%rdx), %xmm0 /* iv */
movdqu (%rdi), %xmm2 movdqu (%rdi), %xmm2 /* first key block */
movdqu 160(%rdi), %xmm12 movdqu 160(%rdi), %xmm12 /* last key block */
xorl %eax, %eax xorl %eax, %eax
// cmpq $8*16, %r9
cmpq $128, %r9 cmpq $128, %r9
jb 1f jb 1f
// leaq -8*16(%r9), %r11
leaq -128(%r9), %r11 leaq -128(%r9), %r11
2: movdqu (%r8, %rax), %xmm3 2: movdqu (%r8, %rax), %xmm3 /* 1st data block */
movdqu 16(%r8, %rax), %xmm4 movdqu 16(%r8, %rax), %xmm4 /* 2d data block */
movdqu 32(%r8, %rax), %xmm5 movdqu 32(%r8, %rax), %xmm5
movdqu 48(%r8, %rax), %xmm6 movdqu 48(%r8, %rax), %xmm6
movdqu 64(%r8, %rax), %xmm7 movdqu 64(%r8, %rax), %xmm7
@ -469,7 +465,7 @@ intel_aes_decrypt_cbc_128:
pxor %xmm12, %xmm9 pxor %xmm12, %xmm9
pxor %xmm12, %xmm10 pxor %xmm12, %xmm10
movq $144, %r10 movq $144, %r10
3: movdqu (%rdi, %r10), %xmm1 3: movdqu (%rdi, %r10), %xmm1 /* n-th block of the key */
.byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */ .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
.byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */ .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
.byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */ .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
@ -488,14 +484,21 @@ intel_aes_decrypt_cbc_128:
.byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
.byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
.byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
pxor %xmm0, %xmm3 pxor %xmm0, %xmm3
pxor (%r8, %rax), %xmm4 movdqu (%r8, %rax), %xmm0
pxor 16(%r8, %rax), %xmm5 pxor %xmm0, %xmm4
pxor 32(%r8, %rax), %xmm6 movdqu 16(%r8, %rax), %xmm0
pxor 48(%r8, %rax), %xmm7 pxor %xmm0, %xmm5
pxor 64(%r8, %rax), %xmm8 movdqu 32(%r8, %rax), %xmm0
pxor 80(%r8, %rax), %xmm9 pxor %xmm0, %xmm6
pxor 96(%r8, %rax), %xmm10 movdqu 48(%r8, %rax), %xmm0
pxor %xmm0, %xmm7
movdqu 64(%r8, %rax), %xmm0
pxor %xmm0, %xmm8
movdqu 80(%r8, %rax), %xmm0
pxor %xmm0, %xmm9
movdqu 96(%r8, %rax), %xmm0
pxor %xmm0, %xmm10
movdqu 112(%r8, %rax), %xmm0 movdqu 112(%r8, %rax), %xmm0
movdqu %xmm3, (%rsi, %rax) movdqu %xmm3, (%rsi, %rax)
movdqu %xmm4, 16(%rsi, %rax) movdqu %xmm4, 16(%rsi, %rax)
@ -505,7 +508,6 @@ intel_aes_decrypt_cbc_128:
movdqu %xmm8, 80(%rsi, %rax) movdqu %xmm8, 80(%rsi, %rax)
movdqu %xmm9, 96(%rsi, %rax) movdqu %xmm9, 96(%rsi, %rax)
movdqu %xmm10, 112(%rsi, %rax) movdqu %xmm10, 112(%rsi, %rax)
// addq $8*16, %rax
addq $128, %rax addq $128, %rax
cmpq %r11, %rax cmpq %r11, %rax
jbe 2b jbe 2b
@ -547,8 +549,7 @@ intel_aes_decrypt_cbc_128:
xor %eax, %eax xor %eax, %eax
ret ret
.size intel_aes_decrypt_cbc_128, .-intel_aes_decrypt_cbc_128 .size intel_aes_decrypt_cbc_128, .-intel_aes_decrypt_cbc_128
/* in %rdi : the key /* in %rdi : the key
in %rsi : buffer for expanded key in %rsi : buffer for expanded key
*/ */
@ -974,8 +975,6 @@ intel_aes_encrypt_cbc_192:
.globl intel_aes_decrypt_cbc_192 .globl intel_aes_decrypt_cbc_192
.align 16 .align 16
intel_aes_decrypt_cbc_192: intel_aes_decrypt_cbc_192:
// leaq IV_OFFSET(%rdi), %rdx
// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
leaq 16(%rdi), %rdx leaq 16(%rdi), %rdx
leaq 48(%rdi), %rdi leaq 48(%rdi), %rdi
@ -983,10 +982,8 @@ intel_aes_decrypt_cbc_192:
movdqu (%rdi), %xmm2 movdqu (%rdi), %xmm2
movdqu 192(%rdi), %xmm14 movdqu 192(%rdi), %xmm14
xorl %eax, %eax xorl %eax, %eax
// cmpq $8*16, %r9
cmpq $128, %r9 cmpq $128, %r9
jb 1f jb 1f
// leaq -8*16(%r9), %r11
leaq -128(%r9), %r11 leaq -128(%r9), %r11
2: movdqu (%r8, %rax), %xmm3 2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4 movdqu 16(%r8, %rax), %xmm4
@ -1024,14 +1021,21 @@ intel_aes_decrypt_cbc_192:
.byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
.byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
.byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
pxor %xmm0, %xmm3 pxor %xmm0, %xmm3
pxor (%r8, %rax), %xmm4 movdqu (%r8, %rax), %xmm0
pxor 16(%r8, %rax), %xmm5 pxor %xmm0, %xmm4
pxor 32(%r8, %rax), %xmm6 movdqu 16(%r8, %rax), %xmm0
pxor 48(%r8, %rax), %xmm7 pxor %xmm0, %xmm5
pxor 64(%r8, %rax), %xmm8 movdqu 32(%r8, %rax), %xmm0
pxor 80(%r8, %rax), %xmm9 pxor %xmm0, %xmm6
pxor 96(%r8, %rax), %xmm10 movdqu 48(%r8, %rax), %xmm0
pxor %xmm0, %xmm7
movdqu 64(%r8, %rax), %xmm0
pxor %xmm0, %xmm8
movdqu 80(%r8, %rax), %xmm0
pxor %xmm0, %xmm9
movdqu 96(%r8, %rax), %xmm0
pxor %xmm0, %xmm10
movdqu 112(%r8, %rax), %xmm0 movdqu 112(%r8, %rax), %xmm0
movdqu %xmm3, (%rsi, %rax) movdqu %xmm3, (%rsi, %rax)
movdqu %xmm4, 16(%rsi, %rax) movdqu %xmm4, 16(%rsi, %rax)
@ -1041,7 +1045,6 @@ intel_aes_decrypt_cbc_192:
movdqu %xmm8, 80(%rsi, %rax) movdqu %xmm8, 80(%rsi, %rax)
movdqu %xmm9, 96(%rsi, %rax) movdqu %xmm9, 96(%rsi, %rax)
movdqu %xmm10, 112(%rsi, %rax) movdqu %xmm10, 112(%rsi, %rax)
// addq $8*16, %rax
addq $128, %rax addq $128, %rax
cmpq %r11, %rax cmpq %r11, %rax
jbe 2b jbe 2b
@ -1088,7 +1091,6 @@ intel_aes_decrypt_cbc_192:
ret ret
.size intel_aes_decrypt_cbc_192, .-intel_aes_decrypt_cbc_192 .size intel_aes_decrypt_cbc_192, .-intel_aes_decrypt_cbc_192
/* in %rdi : the key /* in %rdi : the key
in %rsi : buffer for expanded key in %rsi : buffer for expanded key
*/ */
@ -1296,13 +1298,13 @@ intel_aes_encrypt_ecb_256:
1: cmpq %rax, %r9 1: cmpq %rax, %r9
je 5f je 5f
movdqu (%rdi), %xmm8
movdqu 16(%rdi), %xmm2 movdqu 16(%rdi), %xmm2
movdqu 32(%rdi), %xmm3 movdqu 32(%rdi), %xmm3
movdqu 48(%rdi), %xmm4 movdqu 48(%rdi), %xmm4
movdqu 64(%rdi), %xmm5 movdqu 64(%rdi), %xmm5
movdqu 80(%rdi), %xmm6 movdqu 80(%rdi), %xmm6
movdqu 96(%rdi), %xmm7 movdqu 96(%rdi), %xmm7
movdqu 112(%rdi), %xmm8
movdqu 128(%rdi), %xmm9 movdqu 128(%rdi), %xmm9
movdqu 144(%rdi), %xmm10 movdqu 144(%rdi), %xmm10
movdqu 160(%rdi), %xmm11 movdqu 160(%rdi), %xmm11
@ -1311,7 +1313,8 @@ intel_aes_encrypt_ecb_256:
movdqu 208(%rdi), %xmm14 movdqu 208(%rdi), %xmm14
4: movdqu (%r8, %rax), %xmm1 4: movdqu (%r8, %rax), %xmm1
pxor (%rdi), %xmm1 pxor %xmm8, %xmm1
movdqu 112(%rdi), %xmm8
.byte 0x66,0x0f,0x38,0xdc,0xca /* aesenc %xmm2, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xca /* aesenc %xmm2, %xmm1 */
.byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
.byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
@ -1319,6 +1322,7 @@ intel_aes_encrypt_ecb_256:
.byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
.byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
movdqu (%rdi), %xmm8
.byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
@ -1434,13 +1438,15 @@ intel_aes_decrypt_ecb_256:
.byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
movdqu (%rdi), %xmm8
.byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xca /* aesdec %xmm2, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xca /* aesdec %xmm2, %xmm1 */
.byte 0x66,0x0f,0x38,0xdf,0x0f /* aesdeclast (%rdi), %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdf,0xc8 /* aesdeclast %xmm8, %xmm1 */
movdqu 112(%rdi), %xmm8
movdqu %xmm1, (%rsi, %rax) movdqu %xmm1, (%rsi, %rax)
addq $16, %rax addq $16, %rax
cmpq %rax, %r9 cmpq %rax, %r9
@ -1473,13 +1479,13 @@ intel_aes_encrypt_cbc_256:
leaq 48(%rdi), %rdi leaq 48(%rdi), %rdi
movdqu (%rdx), %xmm0 movdqu (%rdx), %xmm0
movdqu (%rdi), %xmm8
movdqu 16(%rdi), %xmm2 movdqu 16(%rdi), %xmm2
movdqu 32(%rdi), %xmm3 movdqu 32(%rdi), %xmm3
movdqu 48(%rdi), %xmm4 movdqu 48(%rdi), %xmm4
movdqu 64(%rdi), %xmm5 movdqu 64(%rdi), %xmm5
movdqu 80(%rdi), %xmm6 movdqu 80(%rdi), %xmm6
movdqu 96(%rdi), %xmm7 movdqu 96(%rdi), %xmm7
movdqu 112(%rdi), %xmm8
movdqu 128(%rdi), %xmm9 movdqu 128(%rdi), %xmm9
movdqu 144(%rdi), %xmm10 movdqu 144(%rdi), %xmm10
movdqu 160(%rdi), %xmm11 movdqu 160(%rdi), %xmm11
@ -1491,7 +1497,8 @@ intel_aes_encrypt_cbc_256:
xorl %eax, %eax xorl %eax, %eax
1: movdqu (%r8, %rax), %xmm1 1: movdqu (%r8, %rax), %xmm1
pxor %xmm0, %xmm1 pxor %xmm0, %xmm1
pxor (%rdi), %xmm1 pxor %xmm8, %xmm1
movdqu 112(%rdi), %xmm8
.byte 0x66,0x0f,0x38,0xdc,0xca /* aesenc %xmm2, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xca /* aesenc %xmm2, %xmm1 */
.byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
.byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
@ -1499,6 +1506,7 @@ intel_aes_encrypt_cbc_256:
.byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
.byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
movdqu (%rdi), %xmm8
.byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
@ -1582,14 +1590,21 @@ intel_aes_decrypt_cbc_256:
.byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
.byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
.byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */ .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
pxor %xmm0, %xmm3 pxor %xmm0, %xmm3
pxor (%r8, %rax), %xmm4 movdqu (%r8, %rax), %xmm0
pxor 16(%r8, %rax), %xmm5 pxor %xmm0, %xmm4
pxor 32(%r8, %rax), %xmm6 movdqu 16(%r8, %rax), %xmm0
pxor 48(%r8, %rax), %xmm7 pxor %xmm0, %xmm5
pxor 64(%r8, %rax), %xmm8 movdqu 32(%r8, %rax), %xmm0
pxor 80(%r8, %rax), %xmm9 pxor %xmm0, %xmm6
pxor 96(%r8, %rax), %xmm10 movdqu 48(%r8, %rax), %xmm0
pxor %xmm0, %xmm7
movdqu 64(%r8, %rax), %xmm0
pxor %xmm0, %xmm8
movdqu 80(%r8, %rax), %xmm0
pxor %xmm0, %xmm9
movdqu 96(%r8, %rax), %xmm0
pxor %xmm0, %xmm10
movdqu 112(%r8, %rax), %xmm0 movdqu 112(%r8, %rax), %xmm0
movdqu %xmm3, (%rsi, %rax) movdqu %xmm3, (%rsi, %rax)
movdqu %xmm4, 16(%rsi, %rax) movdqu %xmm4, 16(%rsi, %rax)
@ -1629,13 +1644,15 @@ intel_aes_decrypt_cbc_256:
.byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
.byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
movdqu (%rdi), %xmm8
.byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
.byte 0x66,0x0f,0x38,0xde,0xca /* aesdec %xmm2, %xmm1 */ .byte 0x66,0x0f,0x38,0xde,0xca /* aesdec %xmm2, %xmm1 */
.byte 0x66,0x0f,0x38,0xdf,0x0f /* aesdeclast (%rdi), %xmm1 */ .byte 0x66,0x41,0x0f,0x38,0xdf,0xc8 /* aesdeclast %xmm8, %xmm1 */
movdqu 112(%rdi), %xmm8
pxor %xmm0, %xmm1 pxor %xmm0, %xmm1
movdqu %xmm1, (%rsi, %rax) movdqu %xmm1, (%rsi, %rax)
movdqu (%r8, %rax), %xmm0 movdqu (%r8, %rax), %xmm0

Просмотреть файл

@ -0,0 +1,525 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Mozilla Fonudation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif
#include "blapi.h"
#include "secerr.h"
#include "secitem.h"
#include "secmpi.h"
/* Hash an item's length and then its value. Only items smaller than 2^16 bytes
* are allowed. Lengths are hashed in network byte order. This is designed
* to match the OpenSSL J-PAKE implementation.
*/
static mp_err
hashSECItem(HASHContext * hash, const SECItem * it)
{
unsigned char length[2];
if (it->len > 0xffff)
return MP_BADARG;
length[0] = (unsigned char) (it->len >> 8);
length[1] = (unsigned char) (it->len);
hash->hashobj->update(hash->hash_context, length, 2);
hash->hashobj->update(hash->hash_context, it->data, it->len);
return MP_OKAY;
}
/* Hash all public components of the signature, each prefixed with its
length, and then convert the hash to an mp_int. */
static mp_err
hashPublicParams(HASH_HashType hashType, const SECItem * g,
const SECItem * gv, const SECItem * gx,
const SECItem * signerID, mp_int * h)
{
mp_err err;
unsigned char hBuf[HASH_LENGTH_MAX];
SECItem hItem;
HASHContext hash;
hash.hashobj = HASH_GetRawHashObject(hashType);
if (hash.hashobj == NULL || hash.hashobj->length > sizeof hBuf) {
return MP_BADARG;
}
hash.hash_context = hash.hashobj->create();
if (hash.hash_context == NULL) {
return MP_MEM;
}
hItem.data = hBuf;
hItem.len = hash.hashobj->length;
hash.hashobj->begin(hash.hash_context);
CHECK_MPI_OK( hashSECItem(&hash, g) );
CHECK_MPI_OK( hashSECItem(&hash, gv) );
CHECK_MPI_OK( hashSECItem(&hash, gx) );
CHECK_MPI_OK( hashSECItem(&hash, signerID) );
hash.hashobj->end(hash.hash_context, hItem.data, &hItem.len,
sizeof hBuf);
SECITEM_TO_MPINT(hItem, h);
cleanup:
if (hash.hash_context != NULL) {
hash.hashobj->destroy(hash.hash_context, PR_TRUE);
}
return err;
}
/* Generate a Schnorr signature for round 1 or round 2 */
SECStatus
JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
const SECItem * signerID, const SECItem * x,
const SECItem * testRandom, const SECItem * gxIn, SECItem * gxOut,
SECItem * gv, SECItem * r)
{
SECStatus rv = SECSuccess;
mp_err err;
mp_int p;
mp_int q;
mp_int g;
mp_int X;
mp_int GX;
mp_int V;
mp_int GV;
mp_int h;
mp_int tmp;
mp_int R;
SECItem v;
if (!arena ||
!pqg || !pqg->prime.data || pqg->prime.len == 0 ||
!pqg->subPrime.data || pqg->subPrime.len == 0 ||
!pqg->base.data || pqg->base.len == 0 ||
!signerID || !signerID->data || signerID->len == 0 ||
!x || !x->data || x->len == 0 ||
(testRandom && (!testRandom->data || testRandom->len == 0)) ||
(gxIn == NULL && (!gxOut || gxOut->data != NULL)) ||
(gxIn != NULL && (!gxIn->data || gxIn->len == 0 || gxOut != NULL)) ||
!gv || gv->data != NULL ||
!r || r->data != NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
MP_DIGITS(&g) = 0;
MP_DIGITS(&X) = 0;
MP_DIGITS(&GX) = 0;
MP_DIGITS(&V) = 0;
MP_DIGITS(&GV) = 0;
MP_DIGITS(&h) = 0;
MP_DIGITS(&tmp) = 0;
MP_DIGITS(&R) = 0;
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&q) );
CHECK_MPI_OK( mp_init(&g) );
CHECK_MPI_OK( mp_init(&X) );
CHECK_MPI_OK( mp_init(&GX) );
CHECK_MPI_OK( mp_init(&V) );
CHECK_MPI_OK( mp_init(&GV) );
CHECK_MPI_OK( mp_init(&h) );
CHECK_MPI_OK( mp_init(&tmp) );
CHECK_MPI_OK( mp_init(&R) );
SECITEM_TO_MPINT(pqg->prime, &p);
SECITEM_TO_MPINT(pqg->subPrime, &q);
SECITEM_TO_MPINT(pqg->base, &g);
SECITEM_TO_MPINT(*x, &X);
/* gx = g^x */
if (gxIn == NULL) {
CHECK_MPI_OK( mp_exptmod(&g, &X, &p, &GX) );
MPINT_TO_SECITEM(&GX, gxOut, arena);
gxIn = gxOut;
} else {
SECITEM_TO_MPINT(*gxIn, &GX);
}
/* v is a random value in the q subgroup */
if (testRandom == NULL) {
v.data = NULL;
rv = DSA_NewRandom(arena, &pqg->subPrime, &v);
if (rv != SECSuccess) {
goto cleanup;
}
} else {
v.data = testRandom->data;
v.len = testRandom->len;
}
SECITEM_TO_MPINT(v, &V);
/* gv = g^v (mod q), random v, 1 <= v < q */
CHECK_MPI_OK( mp_exptmod(&g, &V, &p, &GV) );
MPINT_TO_SECITEM(&GV, gv, arena);
/* h = H(g, gv, gx, signerID) */
CHECK_MPI_OK( hashPublicParams(hashType, &pqg->base, gv, gxIn, signerID,
&h) );
/* r = v - x*h (mod q) */
CHECK_MPI_OK( mp_mulmod(&X, &h, &q, &tmp) );
CHECK_MPI_OK( mp_submod(&V, &tmp, &q, &R) );
MPINT_TO_SECITEM(&R, r, arena);
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
mp_clear(&X);
mp_clear(&GX);
mp_clear(&V);
mp_clear(&GV);
mp_clear(&h);
mp_clear(&tmp);
mp_clear(&R);
if (rv == SECSuccess && err != MP_OKAY) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
return rv;
}
/* Verify a Schnorr signature generated by the peer in round 1 or round 2. */
SECStatus
JPAKE_Verify(PRArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
const SECItem * signerID, const SECItem * peerID,
const SECItem * gx, const SECItem * gv, const SECItem * r)
{
SECStatus rv = SECSuccess;
mp_err err;
mp_int p;
mp_int q;
mp_int g;
mp_int p_minus_1;
mp_int GX;
mp_int h;
mp_int one;
mp_int R;
mp_int gr;
mp_int gxh;
mp_int gr_gxh;
SECItem calculated;
if (!arena ||
!pqg || !pqg->prime.data || pqg->prime.len == 0 ||
!pqg->subPrime.data || pqg->subPrime.len == 0 ||
!pqg->base.data || pqg->base.len == 0 ||
!signerID || !signerID->data || signerID->len == 0 ||
!peerID || !peerID->data || peerID->len == 0 ||
!gx || !gx->data || gx->len == 0 ||
!gv || !gv->data || gv->len == 0 ||
!r || !r->data || r->len == 0 ||
SECITEM_CompareItem(signerID, peerID) == SECEqual) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
MP_DIGITS(&g) = 0;
MP_DIGITS(&p_minus_1) = 0;
MP_DIGITS(&GX) = 0;
MP_DIGITS(&h) = 0;
MP_DIGITS(&one) = 0;
MP_DIGITS(&R) = 0;
MP_DIGITS(&gr) = 0;
MP_DIGITS(&gxh) = 0;
MP_DIGITS(&gr_gxh) = 0;
calculated.data = NULL;
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&q) );
CHECK_MPI_OK( mp_init(&g) );
CHECK_MPI_OK( mp_init(&p_minus_1) );
CHECK_MPI_OK( mp_init(&GX) );
CHECK_MPI_OK( mp_init(&h) );
CHECK_MPI_OK( mp_init(&one) );
CHECK_MPI_OK( mp_init(&R) );
CHECK_MPI_OK( mp_init(&gr) );
CHECK_MPI_OK( mp_init(&gxh) );
CHECK_MPI_OK( mp_init(&gr_gxh) );
SECITEM_TO_MPINT(pqg->prime, &p);
SECITEM_TO_MPINT(pqg->subPrime, &q);
SECITEM_TO_MPINT(pqg->base, &g);
SECITEM_TO_MPINT(*gx, &GX);
SECITEM_TO_MPINT(*r, &R);
CHECK_MPI_OK( mp_sub_d(&p, 1, &p_minus_1) );
CHECK_MPI_OK( mp_exptmod(&GX, &q, &p, &one) );
/* Check g^x is in [1, p-2], R is in [0, q-1], and (g^x)^q mod p == 1 */
if (!(mp_cmp_z(&GX) > 0 &&
mp_cmp(&GX, &p_minus_1) < 0 &&
mp_cmp(&R, &q) < 0 &&
mp_cmp_d(&one, 1) == 0)) {
goto badSig;
}
CHECK_MPI_OK( hashPublicParams(hashType, &pqg->base, gv, gx, peerID,
&h) );
/* Calculate g^v = g^r * g^x^h */
CHECK_MPI_OK( mp_exptmod(&g, &R, &p, &gr) );
CHECK_MPI_OK( mp_exptmod(&GX, &h, &p, &gxh) );
CHECK_MPI_OK( mp_mulmod(&gr, &gxh, &p, &gr_gxh) );
/* Compare calculated g^v to given g^v */
MPINT_TO_SECITEM(&gr_gxh, &calculated, arena);
if (calculated.len == gv->len &&
NSS_SecureMemcmp(calculated.data, gv->data, calculated.len) == 0) {
rv = SECSuccess;
} else {
badSig: PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
rv = SECFailure;
}
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
mp_clear(&p_minus_1);
mp_clear(&GX);
mp_clear(&h);
mp_clear(&one);
mp_clear(&R);
mp_clear(&gr);
mp_clear(&gxh);
mp_clear(&gr_gxh);
if (rv == SECSuccess && err != MP_OKAY) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
return rv;
}
/* Calculate base = gx1*gx3*gx4 (mod p), i.e. g^(x1+x3+x4) (mod p) */
static mp_err
jpake_Round2Base(const SECItem * gx1, const SECItem * gx3,
const SECItem * gx4, const mp_int * p, mp_int * base)
{
mp_err err;
mp_int GX1;
mp_int GX3;
mp_int GX4;
mp_int tmp;
MP_DIGITS(&GX1) = 0;
MP_DIGITS(&GX3) = 0;
MP_DIGITS(&GX4) = 0;
MP_DIGITS(&tmp) = 0;
CHECK_MPI_OK( mp_init(&GX1) );
CHECK_MPI_OK( mp_init(&GX3) );
CHECK_MPI_OK( mp_init(&GX4) );
CHECK_MPI_OK( mp_init(&tmp) );
SECITEM_TO_MPINT(*gx1, &GX1);
SECITEM_TO_MPINT(*gx3, &GX3);
SECITEM_TO_MPINT(*gx4, &GX4);
/* In round 2, the peer/attacker sends us g^x3 and g^x4 and the protocol
requires that these values are distinct. */
if (mp_cmp(&GX3, &GX4) == 0) {
return MP_BADARG;
}
CHECK_MPI_OK( mp_mul(&GX1, &GX3, &tmp) );
CHECK_MPI_OK( mp_mul(&tmp, &GX4, &tmp) );
CHECK_MPI_OK( mp_mod(&tmp, p, base) );
cleanup:
mp_clear(&GX1);
mp_clear(&GX3);
mp_clear(&GX4);
mp_clear(&tmp);
return err;
}
SECStatus
JPAKE_Round2(PLArenaPool * arena,
const SECItem * p, const SECItem *q, const SECItem * gx1,
const SECItem * gx3, const SECItem * gx4, SECItem * base,
const SECItem * x2, const SECItem * s, SECItem * x2s)
{
mp_err err;
mp_int P;
mp_int Q;
mp_int X2;
mp_int S;
mp_int result;
if (!arena ||
!p || !p->data || p->len == 0 ||
!q || !q->data || q->len == 0 ||
!gx1 || !gx1->data || gx1->len == 0 ||
!gx3 || !gx3->data || gx3->len == 0 ||
!gx4 || !gx4->data || gx4->len == 0 ||
!base || base->data != NULL ||
(x2s != NULL && (x2s->data != NULL ||
!x2 || !x2->data || x2->len == 0 ||
!s || !s->data || s->len == 0))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
MP_DIGITS(&P) = 0;
MP_DIGITS(&Q) = 0;
MP_DIGITS(&X2) = 0;
MP_DIGITS(&S) = 0;
MP_DIGITS(&result) = 0;
CHECK_MPI_OK( mp_init(&P) );
CHECK_MPI_OK( mp_init(&Q) );
CHECK_MPI_OK( mp_init(&result) );
if (x2s != NULL) {
CHECK_MPI_OK( mp_init(&X2) );
CHECK_MPI_OK( mp_init(&S) );
SECITEM_TO_MPINT(*q, &Q);
SECITEM_TO_MPINT(*x2, &X2);
SECITEM_TO_MPINT(*s, &S);
if (mp_cmp(&S, &Q) >= 0) {
err = MP_BADARG;
goto cleanup;
}
CHECK_MPI_OK( mp_mulmod(&X2, &S, &Q, &result) );
MPINT_TO_SECITEM(&result, x2s, arena);
}
SECITEM_TO_MPINT(*p, &P);
CHECK_MPI_OK( jpake_Round2Base(gx1, gx3, gx4, &P, &result) );
MPINT_TO_SECITEM(&result, base, arena);
cleanup:
mp_clear(&P);
mp_clear(&Q);
mp_clear(&X2);
mp_clear(&S);
mp_clear(&result);
if (err != MP_OKAY) {
MP_TO_SEC_ERROR(err);
return SECFailure;
}
return SECSuccess;
}
SECStatus
JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem * q,
const SECItem * x2, const SECItem * gx4, const SECItem * x2s,
const SECItem * B, SECItem * K)
{
mp_err err;
mp_int P;
mp_int Q;
mp_int tmp;
mp_int exponent;
mp_int divisor;
mp_int base;
if (!arena ||
!p || !p->data || p->len == 0 ||
!q || !q->data || q->len == 0 ||
!x2 || !x2->data || x2->len == 0 ||
!gx4 || !gx4->data || gx4->len == 0 ||
!x2s || !x2s->data || x2s->len == 0 ||
!B || !B->data || B->len == 0 ||
!K || K->data != NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
MP_DIGITS(&P) = 0;
MP_DIGITS(&Q) = 0;
MP_DIGITS(&tmp) = 0;
MP_DIGITS(&exponent) = 0;
MP_DIGITS(&divisor) = 0;
MP_DIGITS(&base) = 0;
CHECK_MPI_OK( mp_init(&P) );
CHECK_MPI_OK( mp_init(&Q) );
CHECK_MPI_OK( mp_init(&tmp) );
CHECK_MPI_OK( mp_init(&exponent) );
CHECK_MPI_OK( mp_init(&divisor) );
CHECK_MPI_OK( mp_init(&base) );
/* exponent = -x2s (mod q) */
SECITEM_TO_MPINT(*q, &Q);
SECITEM_TO_MPINT(*x2s, &tmp);
/* q == 0 (mod q), so q - x2s == -x2s (mod q) */
CHECK_MPI_OK( mp_sub(&Q, &tmp, &exponent) );
/* divisor = gx4^-x2s = 1/(gx4^x2s) (mod p) */
SECITEM_TO_MPINT(*p, &P);
SECITEM_TO_MPINT(*gx4, &tmp);
CHECK_MPI_OK( mp_exptmod(&tmp, &exponent, &P, &divisor) );
/* base = B*divisor = B/(gx4^x2s) (mod p) */
SECITEM_TO_MPINT(*B, &tmp);
CHECK_MPI_OK( mp_mulmod(&divisor, &tmp, &P, &base) );
/* tmp = base^x2 (mod p) */
SECITEM_TO_MPINT(*x2, &exponent);
CHECK_MPI_OK( mp_exptmod(&base, &exponent, &P, &tmp) );
MPINT_TO_SECITEM(&tmp, K, arena);
cleanup:
mp_clear(&P);
mp_clear(&Q);
mp_clear(&tmp);
mp_clear(&exponent);
mp_clear(&divisor);
mp_clear(&base);
if (err != MP_OKAY) {
MP_TO_SEC_ERROR(err);
return SECFailure;
}
return SECSuccess;
}

Просмотреть файл

@ -37,7 +37,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: ldvector.c,v 1.21.22.1 2010/07/31 00:11:52 wtc%google.com Exp $ */ /* $Id: ldvector.c,v 1.21.22.3 2010/12/04 18:59:01 rrelyea%redhat.com Exp $ */
#ifdef FREEBL_NO_DEPEND #ifdef FREEBL_NO_DEPEND
extern int FREEBL_InitStubs(void); extern int FREEBL_InitStubs(void);
@ -257,9 +257,20 @@ static const struct FREEBLVectorStr vector =
PRNGTEST_Instantiate, PRNGTEST_Instantiate,
PRNGTEST_Reseed, PRNGTEST_Reseed,
PRNGTEST_Generate, PRNGTEST_Generate,
PRNGTEST_Uninstantiate PRNGTEST_Uninstantiate,
/* End of Version 3.011. */ /* End of Version 3.011. */
RSA_PopulatePrivateKey,
DSA_NewRandom,
JPAKE_Sign,
JPAKE_Verify,
JPAKE_Round2,
JPAKE_Final,
/* End of Version 3.012. */
}; };
const FREEBLVector * const FREEBLVector *

Просмотреть файл

@ -37,7 +37,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: loader.c,v 1.44 2009/03/29 03:45:32 wtc%google.com Exp $ */ /* $Id: loader.c,v 1.44.22.2 2010/12/04 18:59:01 rrelyea%redhat.com Exp $ */
#include "loader.h" #include "loader.h"
#include "prmem.h" #include "prmem.h"
@ -295,6 +295,14 @@ DSA_SignDigestWithSeed(DSAPrivateKey * key, SECItem * signature,
return (vector->p_DSA_SignDigestWithSeed)( key, signature, digest, seed); return (vector->p_DSA_SignDigestWithSeed)( key, signature, digest, seed);
} }
SECStatus
DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_DSA_NewRandom)(arena, q, seed);
}
SECStatus SECStatus
DH_GenParam(int primeLen, DHParams ** params) DH_GenParam(int primeLen, DHParams ** params)
{ {
@ -1696,4 +1704,54 @@ PRNGTEST_Uninstantiate()
return (vector->p_PRNGTEST_Uninstantiate)(); return (vector->p_PRNGTEST_Uninstantiate)();
} }
SECStatus
RSA_PopulatePrivateKey(RSAPrivateKey *key)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_RSA_PopulatePrivateKey)(key);
}
SECStatus
JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
const SECItem * signerID, const SECItem * x,
const SECItem * testRandom, const SECItem * gxIn, SECItem * gxOut,
SECItem * gv, SECItem * r)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_JPAKE_Sign)(arena, pqg, hashType, signerID, x,
testRandom, gxIn, gxOut, gv, r);
}
SECStatus
JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg,
HASH_HashType hashType, const SECItem * signerID,
const SECItem * peerID, const SECItem * gx,
const SECItem * gv, const SECItem * r)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_JPAKE_Verify)(arena, pqg, hashType, signerID, peerID,
gx, gv, r);
}
SECStatus
JPAKE_Round2(PLArenaPool * arena, const SECItem * p, const SECItem *q,
const SECItem * gx1, const SECItem * gx3, const SECItem * gx4,
SECItem * base, const SECItem * x2, const SECItem * s, SECItem * x2s)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_JPAKE_Round2)(arena, p, q, gx1, gx3, gx4, base, x2, s, x2s);
}
SECStatus
JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem *q,
const SECItem * x2, const SECItem * gx4, const SECItem * x2s,
const SECItem * B, SECItem * K)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_JPAKE_Final)(arena, p, q, x2, gx4, x2s, B, K);
}

Просмотреть файл

@ -37,14 +37,14 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: loader.h,v 1.26 2009/03/29 03:45:32 wtc%google.com Exp $ */ /* $Id: loader.h,v 1.26.22.2 2010/12/04 18:59:01 rrelyea%redhat.com Exp $ */
#ifndef _LOADER_H_ #ifndef _LOADER_H_
#define _LOADER_H_ 1 #define _LOADER_H_ 1
#include "blapi.h" #include "blapi.h"
#define FREEBL_VERSION 0x030B #define FREEBL_VERSION 0x030C
struct FREEBLVectorStr { struct FREEBLVectorStr {
@ -540,6 +540,37 @@ struct FREEBLVectorStr {
SECStatus (* p_PRNGTEST_Uninstantiate)(void); SECStatus (* p_PRNGTEST_Uninstantiate)(void);
/* Version 3.011 came to here */ /* Version 3.011 came to here */
SECStatus (*p_RSA_PopulatePrivateKey)(RSAPrivateKey *key);
SECStatus (*p_DSA_NewRandom)(PLArenaPool * arena, const SECItem * q,
SECItem * seed);
SECStatus (*p_JPAKE_Sign)(PLArenaPool * arena, const PQGParams * pqg,
HASH_HashType hashType, const SECItem * signerID,
const SECItem * x, const SECItem * testRandom,
const SECItem * gxIn, SECItem * gxOut,
SECItem * gv, SECItem * r);
SECStatus (*p_JPAKE_Verify)(PLArenaPool * arena, const PQGParams * pqg,
HASH_HashType hashType, const SECItem * signerID,
const SECItem * peerID, const SECItem * gx,
const SECItem * gv, const SECItem * r);
SECStatus (*p_JPAKE_Round2)(PLArenaPool * arena, const SECItem * p,
const SECItem *q, const SECItem * gx1,
const SECItem * gx3, const SECItem * gx4,
SECItem * base, const SECItem * x2,
const SECItem * s, SECItem * x2s);
SECStatus (*p_JPAKE_Final)(PLArenaPool * arena, const SECItem * p,
const SECItem *q, const SECItem * x2,
const SECItem * gx4, const SECItem * x2s,
const SECItem * B, SECItem * K);
/* Version 3.012 came to here */
}; };
typedef struct FREEBLVectorStr FREEBLVector; typedef struct FREEBLVectorStr FREEBLVector;

Просмотреть файл

@ -146,6 +146,7 @@ CSRCS = \
shvfy.c \ shvfy.c \
tlsprfalg.c \ tlsprfalg.c \
seed.c \ seed.c \
jpake.c \
$(MPI_SRCS) \ $(MPI_SRCS) \
$(MPCPU_SRCS) \ $(MPCPU_SRCS) \
$(ECL_SRCS) \ $(ECL_SRCS) \

Просмотреть файл

@ -33,7 +33,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: rijndael.c,v 1.25 2009/04/09 22:11:07 julien.pierre.boogz%sun.com Exp $ */ /* $Id: rijndael.c,v 1.25.6.1 2010/11/18 01:33:42 rrelyea%redhat.com Exp $ */
#ifdef FREEBL_NO_DEPEND #ifdef FREEBL_NO_DEPEND
#include "stubs.h" #include "stubs.h"
@ -1027,9 +1027,14 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
#if USE_HW_AES #if USE_HW_AES
if (has_intel_aes == 0) { if (has_intel_aes == 0) {
unsigned long eax, ebx, ecx, edx; unsigned long eax, ebx, ecx, edx;
char *disable_hw_aes = getenv("NSS_DISABLE_HW_AES");
freebl_cpuid(1, &eax, &ebx, &ecx, &edx); if (disable_hw_aes == NULL) {
has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1; freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1;
} else {
has_intel_aes = -1;
}
} }
use_hw_aes = (PRBool) use_hw_aes = (PRBool)
(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16); (has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);

Просмотреть файл

@ -37,7 +37,7 @@
/* /*
* RSA key generation, public key op, private key op. * RSA key generation, public key op, private key op.
* *
* $Id: rsa.c,v 1.39 2009/02/03 05:34:41 julien.pierre.boogz%sun.com Exp $ * $Id: rsa.c,v 1.39.22.1 2010/11/16 19:06:38 rrelyea%redhat.com Exp $
*/ */
#ifdef FREEBL_NO_DEPEND #ifdef FREEBL_NO_DEPEND
#include "stubs.h" #include "stubs.h"
@ -116,21 +116,21 @@ static struct RSABlindingParamsListStr blindingParamsList = { 0 };
static PRBool nssRSAUseBlinding = PR_TRUE; static PRBool nssRSAUseBlinding = PR_TRUE;
static SECStatus static SECStatus
rsa_keygen_from_primes(mp_int *p, mp_int *q, mp_int *e, RSAPrivateKey *key, rsa_build_from_primes(mp_int *p, mp_int *q,
unsigned int keySizeInBits) mp_int *e, PRBool needPublicExponent,
mp_int *d, PRBool needPrivateExponent,
RSAPrivateKey *key, unsigned int keySizeInBits)
{ {
mp_int n, d, phi; mp_int n, phi;
mp_int psub1, qsub1, tmp; mp_int psub1, qsub1, tmp;
mp_err err = MP_OKAY; mp_err err = MP_OKAY;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
MP_DIGITS(&n) = 0; MP_DIGITS(&n) = 0;
MP_DIGITS(&d) = 0;
MP_DIGITS(&phi) = 0; MP_DIGITS(&phi) = 0;
MP_DIGITS(&psub1) = 0; MP_DIGITS(&psub1) = 0;
MP_DIGITS(&qsub1) = 0; MP_DIGITS(&qsub1) = 0;
MP_DIGITS(&tmp) = 0; MP_DIGITS(&tmp) = 0;
CHECK_MPI_OK( mp_init(&n) ); CHECK_MPI_OK( mp_init(&n) );
CHECK_MPI_OK( mp_init(&d) );
CHECK_MPI_OK( mp_init(&phi) ); CHECK_MPI_OK( mp_init(&phi) );
CHECK_MPI_OK( mp_init(&psub1) ); CHECK_MPI_OK( mp_init(&psub1) );
CHECK_MPI_OK( mp_init(&qsub1) ); CHECK_MPI_OK( mp_init(&qsub1) );
@ -143,12 +143,25 @@ rsa_keygen_from_primes(mp_int *p, mp_int *q, mp_int *e, RSAPrivateKey *key,
rv = SECFailure; rv = SECFailure;
goto cleanup; goto cleanup;
} }
/* at least one exponent must be given */
PORT_Assert(!(needPublicExponent && needPrivateExponent));
/* 2. Compute phi = (p-1)*(q-1) */ /* 2. Compute phi = (p-1)*(q-1) */
CHECK_MPI_OK( mp_sub_d(p, 1, &psub1) ); CHECK_MPI_OK( mp_sub_d(p, 1, &psub1) );
CHECK_MPI_OK( mp_sub_d(q, 1, &qsub1) ); CHECK_MPI_OK( mp_sub_d(q, 1, &qsub1) );
CHECK_MPI_OK( mp_mul(&psub1, &qsub1, &phi) ); if (needPublicExponent || needPrivateExponent) {
/* 3. Compute d = e**-1 mod(phi) */ CHECK_MPI_OK( mp_mul(&psub1, &qsub1, &phi) );
err = mp_invmod(e, &phi, &d); /* 3. Compute d = e**-1 mod(phi) */
/* or e = d**-1 mod(phi) as necessary */
if (needPublicExponent) {
err = mp_invmod(d, &phi, e);
} else {
err = mp_invmod(e, &phi, d);
}
} else {
err = MP_OKAY;
}
/* Verify that phi(n) and e have no common divisors */ /* Verify that phi(n) and e have no common divisors */
if (err != MP_OKAY) { if (err != MP_OKAY) {
if (err == MP_UNDEF) { if (err == MP_UNDEF) {
@ -158,20 +171,30 @@ rsa_keygen_from_primes(mp_int *p, mp_int *q, mp_int *e, RSAPrivateKey *key,
} }
goto cleanup; goto cleanup;
} }
MPINT_TO_SECITEM(&n, &key->modulus, key->arena);
MPINT_TO_SECITEM(&d, &key->privateExponent, key->arena);
/* 4. Compute exponent1 = d mod (p-1) */ /* 4. Compute exponent1 = d mod (p-1) */
CHECK_MPI_OK( mp_mod(&d, &psub1, &tmp) ); CHECK_MPI_OK( mp_mod(d, &psub1, &tmp) );
MPINT_TO_SECITEM(&tmp, &key->exponent1, key->arena); MPINT_TO_SECITEM(&tmp, &key->exponent1, key->arena);
/* 5. Compute exponent2 = d mod (q-1) */ /* 5. Compute exponent2 = d mod (q-1) */
CHECK_MPI_OK( mp_mod(&d, &qsub1, &tmp) ); CHECK_MPI_OK( mp_mod(d, &qsub1, &tmp) );
MPINT_TO_SECITEM(&tmp, &key->exponent2, key->arena); MPINT_TO_SECITEM(&tmp, &key->exponent2, key->arena);
/* 6. Compute coefficient = q**-1 mod p */ /* 6. Compute coefficient = q**-1 mod p */
CHECK_MPI_OK( mp_invmod(q, p, &tmp) ); CHECK_MPI_OK( mp_invmod(q, p, &tmp) );
MPINT_TO_SECITEM(&tmp, &key->coefficient, key->arena); MPINT_TO_SECITEM(&tmp, &key->coefficient, key->arena);
/* copy our calculated results, overwrite what is there */
key->modulus.data = NULL;
MPINT_TO_SECITEM(&n, &key->modulus, key->arena);
key->privateExponent.data = NULL;
MPINT_TO_SECITEM(d, &key->privateExponent, key->arena);
key->publicExponent.data = NULL;
MPINT_TO_SECITEM(e, &key->publicExponent, key->arena);
key->prime1.data = NULL;
MPINT_TO_SECITEM(p, &key->prime1, key->arena);
key->prime2.data = NULL;
MPINT_TO_SECITEM(q, &key->prime2, key->arena);
cleanup: cleanup:
mp_clear(&n); mp_clear(&n);
mp_clear(&d);
mp_clear(&phi); mp_clear(&phi);
mp_clear(&psub1); mp_clear(&psub1);
mp_clear(&qsub1); mp_clear(&qsub1);
@ -229,7 +252,7 @@ RSAPrivateKey *
RSA_NewKey(int keySizeInBits, SECItem *publicExponent) RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
{ {
unsigned int primeLen; unsigned int primeLen;
mp_int p, q, e; mp_int p, q, e, d;
int kiter; int kiter;
mp_err err = MP_OKAY; mp_err err = MP_OKAY;
SECStatus rv = SECSuccess; SECStatus rv = SECSuccess;
@ -260,14 +283,15 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
MP_DIGITS(&p) = 0; MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0; MP_DIGITS(&q) = 0;
MP_DIGITS(&e) = 0; MP_DIGITS(&e) = 0;
MP_DIGITS(&d) = 0;
CHECK_MPI_OK( mp_init(&p) ); CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&q) ); CHECK_MPI_OK( mp_init(&q) );
CHECK_MPI_OK( mp_init(&e) ); CHECK_MPI_OK( mp_init(&e) );
CHECK_MPI_OK( mp_init(&d) );
/* 2. Set the version number (PKCS1 v1.5 says it should be zero) */ /* 2. Set the version number (PKCS1 v1.5 says it should be zero) */
SECITEM_AllocItem(arena, &key->version, 1); SECITEM_AllocItem(arena, &key->version, 1);
key->version.data[0] = 0; key->version.data[0] = 0;
/* 3. Set the public exponent */ /* 3. Set the public exponent */
SECITEM_CopyItem(arena, &key->publicExponent, publicExponent);
SECITEM_TO_MPINT(*publicExponent, &e); SECITEM_TO_MPINT(*publicExponent, &e);
kiter = 0; kiter = 0;
do { do {
@ -279,7 +303,10 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
if (mp_cmp(&p, &q) < 0) if (mp_cmp(&p, &q) < 0)
mp_exch(&p, &q); mp_exch(&p, &q);
/* Attempt to use these primes to generate a key */ /* Attempt to use these primes to generate a key */
rv = rsa_keygen_from_primes(&p, &q, &e, key, keySizeInBits); rv = rsa_build_from_primes(&p, &q,
&e, PR_FALSE, /* needPublicExponent=false */
&d, PR_TRUE, /* needPrivateExponent=true */
key, keySizeInBits);
if (rv == SECSuccess) if (rv == SECSuccess)
break; /* generated two good primes */ break; /* generated two good primes */
prerr = PORT_GetError(); prerr = PORT_GetError();
@ -288,12 +315,11 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
} while (prerr == SEC_ERROR_NEED_RANDOM && kiter < MAX_KEY_GEN_ATTEMPTS); } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < MAX_KEY_GEN_ATTEMPTS);
if (prerr) if (prerr)
goto cleanup; goto cleanup;
MPINT_TO_SECITEM(&p, &key->prime1, arena);
MPINT_TO_SECITEM(&q, &key->prime2, arena);
cleanup: cleanup:
mp_clear(&p); mp_clear(&p);
mp_clear(&q); mp_clear(&q);
mp_clear(&e); mp_clear(&e);
mp_clear(&d);
if (err) { if (err) {
MP_TO_SEC_ERROR(err); MP_TO_SEC_ERROR(err);
rv = SECFailure; rv = SECFailure;
@ -305,6 +331,484 @@ cleanup:
return key; return key;
} }
mp_err
rsa_is_prime(mp_int *p) {
int res;
/* run a Fermat test */
res = mpp_fermat(p, 2);
if (res != MP_OKAY) {
return res;
}
/* If that passed, run some Miller-Rabin tests */
res = mpp_pprime(p, 2);
return res;
}
/*
* Try to find the two primes based on 2 exponents plus either a prime
* or a modulus.
*
* In: e, d and either p or n (depending on the setting of hasModulus).
* Out: p,q.
*
* Step 1, Since d = e**-1 mod phi, we know that d*e == 1 mod phi, or
* d*e = 1+k*phi, or d*e-1 = k*phi. since d is less than phi and e is
* usually less than d, then k must be an integer between e-1 and 1
* (probably on the order of e).
* Step 1a, If we were passed just a prime, we can divide k*phi by that
* prime-1 and get k*(q-1). This will reduce the size of our division
* through the rest of the loop.
* Step 2, Loop through the values k=e-1 to 1 looking for k. k should be on
* the order or e, and e is typically small. This may take a while for
* a large random e. We are looking for a k that divides kphi
* evenly. Once we find a k that divides kphi evenly, we assume it
* is the true k. It's possible this k is not the 'true' k but has
* swapped factors of p-1 and/or q-1. Because of this, we
* tentatively continue Steps 3-6 inside this loop, and may return looking
* for another k on failure.
* Step 3, Calculate are tentative phi=kphi/k. Note: real phi is (p-1)*(q-1).
* Step 4a, if we have a prime, kphi is already k*(q-1), so phi is or tenative
* q-1. q = phi+1. If k is correct, q should be the right length and
* prime.
* Step 4b, It's possible q-1 and k could have swapped factors. We now have a
* possible solution that meets our criteria. It may not be the only
* solution, however, so we keep looking. If we find more than one,
* we will fail since we cannot determine which is the correct
* solution, and returning the wrong modulus will compromise both
* moduli. If no other solution is found, we return the unique solution.
* Step 5a, If we have the modulus (n=pq), then use the following formula to
* calculate s=(p+q): , phi = (p-1)(q-1) = pq -p-q +1 = n-s+1. so
* s=n-phi+1.
* Step 5b, Use n=pq and s=p+q to solve for p and q as follows:
* since q=s-p, then n=p*(s-p)= sp - p^2, rearranging p^2-s*p+n = 0.
* from the quadratic equation we have p=1/2*(s+sqrt(s*s-4*n)) and
* q=1/2*(s-sqrt(s*s-4*n)) if s*s-4*n is a perfect square, we are DONE.
* If it is not, continue in our look looking for another k. NOTE: the
* code actually distributes the 1/2 and results in the equations:
* sqrt = sqrt(s/2*s/2-n), p=s/2+sqrt, q=s/2-sqrt. The algebra saves us
* and extra divide by 2 and a multiply by 4.
*
* This will return p & q. q may be larger than p in the case that p was given
* and it was the smaller prime.
*/
static mp_err
rsa_get_primes_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
mp_int *n, PRBool hasModulus,
unsigned int keySizeInBits)
{
mp_int kphi; /* k*phi */
mp_int k; /* current guess at 'k' */
mp_int phi; /* (p-1)(q-1) */
mp_int s; /* p+q/2 (s/2 in the algebra) */
mp_int r; /* remainder */
mp_int tmp; /* p-1 if p is given, n+1 is modulus is given */
mp_int sqrt; /* sqrt(s/2*s/2-n) */
mp_err err = MP_OKAY;
unsigned int order_k;
MP_DIGITS(&kphi) = 0;
MP_DIGITS(&phi) = 0;
MP_DIGITS(&s) = 0;
MP_DIGITS(&k) = 0;
MP_DIGITS(&r) = 0;
MP_DIGITS(&tmp) = 0;
MP_DIGITS(&sqrt) = 0;
CHECK_MPI_OK( mp_init(&kphi) );
CHECK_MPI_OK( mp_init(&phi) );
CHECK_MPI_OK( mp_init(&s) );
CHECK_MPI_OK( mp_init(&k) );
CHECK_MPI_OK( mp_init(&r) );
CHECK_MPI_OK( mp_init(&tmp) );
CHECK_MPI_OK( mp_init(&sqrt) );
/* our algorithm looks for a factor k whose maximum size is dependent
* on the size of our smallest exponent, which had better be the public
* exponent (if it's the private, the key is vulnerable to a brute force
* attack).
*
* since our factor search is linear, we need to limit the maximum
* size of the public key. this should not be a problem normally, since
* public keys are usually small.
*
* if we want to handle larger public key sizes, we should have
* a version which tries to 'completely' factor k*phi (where completely
* means 'factor into primes, or composites with which are products of
* large primes). Once we have all the factors, we can sort them out and
* try different combinations to form our phi. The risk is if (p-1)/2,
* (q-1)/2, and k are all large primes. In any case if the public key
* is small (order of 20 some bits), then a linear search for k is
* manageable.
*/
if (mpl_significant_bits(e) > 23) {
err=MP_RANGE;
goto cleanup;
}
/* calculate k*phi = e*d - 1 */
CHECK_MPI_OK( mp_mul(e, d, &kphi) );
CHECK_MPI_OK( mp_sub_d(&kphi, 1, &kphi) );
/* kphi is (e*d)-1, which is the same as k*(p-1)(q-1)
* d < (p-1)(q-1), therefor k must be less than e-1
* We can narrow down k even more, though. Since p and q are odd and both
* have their high bit set, then we know that phi must be on order of
* keySizeBits.
*/
order_k = (unsigned)mpl_significant_bits(&kphi) - keySizeInBits;
/* for (k=kinit; order(k) >= order_k; k--) { */
/* k=kinit: k can't be bigger than kphi/2^(keySizeInBits -1) */
CHECK_MPI_OK( mp_2expt(&k,keySizeInBits-1) );
CHECK_MPI_OK( mp_div(&kphi, &k, &k, NULL));
if (mp_cmp(&k,e) >= 0) {
/* also can't be bigger then e-1 */
CHECK_MPI_OK( mp_sub_d(e, 1, &k) );
}
/* calculate our temp value */
/* This saves recalculating this value when the k guess is wrong, which
* is reasonably frequent. */
/* for the modulus case, tmp = n+1 (used to calculate p+q = tmp - phi) */
/* for the prime case, tmp = p-1 (used to calculate q-1= phi/tmp) */
if (hasModulus) {
CHECK_MPI_OK( mp_add_d(n, 1, &tmp) );
} else {
CHECK_MPI_OK( mp_sub_d(p, 1, &tmp) );
CHECK_MPI_OK(mp_div(&kphi,&tmp,&kphi,&r));
if (mp_cmp_z(&r) != 0) {
/* p-1 doesn't divide kphi, some parameter wasn't correct */
err=MP_RANGE;
goto cleanup;
}
mp_zero(q);
/* kphi is now k*(q-1) */
}
/* rest of the for loop */
for (; (err == MP_OKAY) && (mpl_significant_bits(&k) >= order_k);
err = mp_sub_d(&k, 1, &k)) {
/* looking for k as a factor of kphi */
CHECK_MPI_OK(mp_div(&kphi,&k,&phi,&r));
if (mp_cmp_z(&r) != 0) {
/* not a factor, try the next one */
continue;
}
/* we have a possible phi, see if it works */
if (!hasModulus) {
if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits/2) {
/* phi is not the right size */
continue;
}
/* phi should be divisible by 2, since
* q is odd and phi=(q-1). */
if (mpp_divis_d(&phi,2) == MP_NO) {
/* phi is not divisible by 4 */
continue;
}
/* we now have a candidate for the second prime */
CHECK_MPI_OK(mp_add_d(&phi, 1, &tmp));
/* check to make sure it is prime */
err = rsa_is_prime(&tmp);
if (err != MP_OKAY) {
if (err == MP_NO) {
/* No, then we still have the wrong phi */
err = MP_OKAY;
continue;
}
goto cleanup;
}
/*
* It is possible that we have the wrong phi if
* k_guess*(q_guess-1) = k*(q-1) (k and q-1 have swapped factors).
* since our q_quess is prime, however. We have found a valid
* rsa key because:
* q is the correct order of magnitude.
* phi = (p-1)(q-1) where p and q are both primes.
* e*d mod phi = 1.
* There is no way to know from the info given if this is the
* original key. We never want to return the wrong key because if
* two moduli with the same factor is known, then euclid's gcd
* algorithm can be used to find that factor. Even though the
* caller didn't pass the original modulus, it doesn't mean the
* modulus wasn't known or isn't available somewhere. So to be safe
* if we can't be sure we have the right q, we don't return any.
*
* So to make sure we continue looking for other valid q's. If none
* are found, then we can safely return this one, otherwise we just
* fail */
if (mp_cmp_z(q) != 0) {
/* this is the second valid q, don't return either,
* just fail */
err = MP_RANGE;
break;
}
/* we only have one q so far, save it and if no others are found,
* it's safe to return it */
CHECK_MPI_OK(mp_copy(&tmp, q));
continue;
}
/* test our tentative phi */
/* phi should be the correct order */
if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits) {
/* phi is not the right size */
continue;
}
/* phi should be divisible by 4, since
* p and q are odd and phi=(p-1)(q-1). */
if (mpp_divis_d(&phi,4) == MP_NO) {
/* phi is not divisible by 4 */
continue;
}
/* n was given, calculate s/2=(p+q)/2 */
CHECK_MPI_OK( mp_sub(&tmp, &phi, &s) );
CHECK_MPI_OK( mp_div_2(&s, &s) );
/* calculate sqrt(s/2*s/2-n) */
CHECK_MPI_OK(mp_sqr(&s,&sqrt));
CHECK_MPI_OK(mp_sub(&sqrt,n,&r)); /* r as a tmp */
CHECK_MPI_OK(mp_sqrt(&r,&sqrt));
/* make sure it's a perfect square */
/* r is our original value we took the square root of */
/* q is the square of our tentative square root. They should be equal*/
CHECK_MPI_OK(mp_sqr(&sqrt,q)); /* q as a tmp */
if (mp_cmp(&r,q) != 0) {
/* sigh according to the doc, mp_sqrt could return sqrt-1 */
CHECK_MPI_OK(mp_add_d(&sqrt,1,&sqrt));
CHECK_MPI_OK(mp_sqr(&sqrt,q));
if (mp_cmp(&r,q) != 0) {
/* s*s-n not a perfect square, this phi isn't valid, find * another.*/
continue;
}
}
/* NOTE: In this case we know we have the one and only answer.
* "Why?", you ask. Because:
* 1) n is a composite of two large primes (or it wasn't a
* valid RSA modulus).
* 2) If we know any number such that x^2-n is a perfect square
* and x is not (n+1)/2, then we can calculate 2 non-trivial
* factors of n.
* 3) Since we know that n has only 2 non-trivial prime factors,
* we know the two factors we have are the only possible factors.
*/
/* Now we are home free to calculate p and q */
/* p = s/2 + sqrt, q= s/2 - sqrt */
CHECK_MPI_OK(mp_add(&s,&sqrt,p));
CHECK_MPI_OK(mp_sub(&s,&sqrt,q));
break;
}
if ((unsigned)mpl_significant_bits(&k) < order_k) {
if (hasModulus || (mp_cmp_z(q) == 0)) {
/* If we get here, something was wrong with the parameters we
* were given */
err = MP_RANGE;
}
}
cleanup:
mp_clear(&kphi);
mp_clear(&phi);
mp_clear(&s);
mp_clear(&k);
mp_clear(&r);
mp_clear(&tmp);
mp_clear(&sqrt);
return err;
}
/*
* take a private key with only a few elements and fill out the missing pieces.
*
* All the entries will be overwritten with data allocated out of the arena
* If no arena is supplied, one will be created.
*
* The following fields must be supplied in order for this function
* to succeed:
* one of either publicExponent or privateExponent
* two more of the following 5 parameters.
* modulus (n)
* prime1 (p)
* prime2 (q)
* publicExponent (e)
* privateExponent (d)
*
* NOTE: if only the publicExponent, privateExponent, and one prime is given,
* then there may be more than one RSA key that matches that combination.
*
* All parameters will be replaced in the key structure with new parameters
* Allocated out of the arena. There is no attempt to free the old structures.
* Prime1 will always be greater than prime2 (even if the caller supplies the
* smaller prime as prime1 or the larger prime as prime2). The parameters are
* not overwritten on failure.
*
* How it works:
* We can generate all the parameters from:
* one of the exponents, plus the two primes. (rsa_build_key_from_primes) *
* If we are given one of the exponents and both primes, we are done.
* If we are given one of the exponents, the modulus and one prime, we
* caclulate the second prime by dividing the modulus by the given
* prime, giving us and exponent and 2 primes.
* If we are given 2 exponents and either the modulus or one of the primes
* we calculate k*phi = d*e-1, where k is an integer less than d which
* divides d*e-1. We find factor k so we can isolate phi.
* phi = (p-1)(q-1)
* If one of the primes are given, we can use phi to find the other prime
* as follows: q = (phi/(p-1)) + 1. We now have 2 primes and an
* exponent. (NOTE: if more then one prime meets this condition, the
* operation will fail. See comments elsewhere in this file about this).
* If the modulus is given, then we can calculate the sum of the primes
* as follows: s := (p+q), phi = (p-1)(q-1) = pq -p - q +1, pq = n ->
* phi = n - s + 1, s = n - phi +1. Now that we have s = p+q and n=pq,
* we can solve our 2 equations and 2 unknowns as follows: q=s-p ->
* n=p*(s-p)= sp -p^2 -> p^2-sp+n = 0. Using the quadratic to solve for
* p, p=1/2*(s+ sqrt(s*s-4*n)) [q=1/2*(s-sqrt(s*s-4*n)]. We again have
* 2 primes and an exponent.
*
*/
SECStatus
RSA_PopulatePrivateKey(RSAPrivateKey *key)
{
PRArenaPool *arena = NULL;
PRBool needPublicExponent = PR_TRUE;
PRBool needPrivateExponent = PR_TRUE;
PRBool hasModulus = PR_FALSE;
unsigned int keySizeInBits = 0;
int prime_count = 0;
/* standard RSA nominclature */
mp_int p, q, e, d, n;
/* remainder */
mp_int r;
mp_err err = 0;
SECStatus rv = SECFailure;
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
MP_DIGITS(&e) = 0;
MP_DIGITS(&d) = 0;
MP_DIGITS(&n) = 0;
MP_DIGITS(&r) = 0;
CHECK_MPI_OK( mp_init(&p) );
CHECK_MPI_OK( mp_init(&q) );
CHECK_MPI_OK( mp_init(&e) );
CHECK_MPI_OK( mp_init(&d) );
CHECK_MPI_OK( mp_init(&n) );
CHECK_MPI_OK( mp_init(&r) );
/* if the key didn't already have an arena, create one. */
if (key->arena == NULL) {
arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
if (!arena) {
goto cleanup;
}
key->arena = arena;
}
/* load up the known exponents */
if (key->publicExponent.data) {
SECITEM_TO_MPINT(key->publicExponent, &e);
needPublicExponent = PR_FALSE;
}
if (key->privateExponent.data) {
SECITEM_TO_MPINT(key->privateExponent, &d);
needPrivateExponent = PR_FALSE;
}
if (needPrivateExponent && needPublicExponent) {
/* Not enough information, we need at least one exponent */
err = MP_BADARG;
goto cleanup;
}
/* load up the known primes. If only one prime is given, it will be
* assigned 'p'. Once we have both primes, well make sure p is the larger.
* The value prime_count tells us howe many we have acquired.
*/
if (key->prime1.data) {
int primeLen = key->prime1.len;
if (key->prime1.data[0] == 0) {
primeLen--;
}
keySizeInBits = primeLen * 2 * BITS_PER_BYTE;
SECITEM_TO_MPINT(key->prime1, &p);
prime_count++;
}
if (key->prime2.data) {
int primeLen = key->prime2.len;
if (key->prime2.data[0] == 0) {
primeLen--;
}
keySizeInBits = primeLen * 2 * BITS_PER_BYTE;
SECITEM_TO_MPINT(key->prime2, prime_count ? &q : &p);
prime_count++;
}
/* load up the modulus */
if (key->modulus.data) {
int modLen = key->modulus.len;
if (key->modulus.data[0] == 0) {
modLen--;
}
keySizeInBits = modLen * BITS_PER_BYTE;
SECITEM_TO_MPINT(key->modulus, &n);
hasModulus = PR_TRUE;
}
/* if we have the modulus and one prime, calculate the second. */
if ((prime_count == 1) && (hasModulus)) {
mp_div(&n,&p,&q,&r);
if (mp_cmp_z(&r) != 0) {
/* p is not a factor or n, fail */
err = MP_BADARG;
goto cleanup;
}
prime_count++;
}
/* If we didn't have enough primes try to calculate the primes from
* the exponents */
if (prime_count < 2) {
/* if we don't have at least 2 primes at this point, then we need both
* exponents and one prime or a modulus*/
if (!needPublicExponent && !needPrivateExponent &&
((prime_count > 0) || hasModulus)) {
CHECK_MPI_OK(rsa_get_primes_from_exponents(&e,&d,&p,&q,
&n,hasModulus,keySizeInBits));
} else {
/* not enough given parameters to get both primes */
err = MP_BADARG;
goto cleanup;
}
}
/* force p to the the larger prime */
if (mp_cmp(&p, &q) < 0)
mp_exch(&p, &q);
/* we now have our 2 primes and at least one exponent, we can fill
* in the key */
rv = rsa_build_from_primes(&p, &q,
&e, needPublicExponent,
&d, needPrivateExponent,
key, keySizeInBits);
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&e);
mp_clear(&d);
mp_clear(&n);
mp_clear(&r);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
if (rv && arena) {
PORT_FreeArena(arena, PR_TRUE);
key->arena = NULL;
}
return rv;
}
static unsigned int static unsigned int
rsa_modulusLen(SECItem *modulus) rsa_modulusLen(SECItem *modulus)
{ {

Просмотреть файл

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: sha512.c,v 1.14 2009/04/09 22:11:07 julien.pierre.boogz%sun.com Exp $ */ /* $Id: sha512.c,v 1.14.6.1 2010/11/18 18:32:52 kaie%kuix.de Exp $ */
#ifdef FREEBL_NO_DEPEND #ifdef FREEBL_NO_DEPEND
#include "stubs.h" #include "stubs.h"
@ -48,6 +48,7 @@
#undef HAVE_LONG_LONG #undef HAVE_LONG_LONG
#endif #endif
#include "prtypes.h" /* for PRUintXX */ #include "prtypes.h" /* for PRUintXX */
#include "prlong.h"
#include "secport.h" /* for PORT_XXX */ #include "secport.h" /* for PORT_XXX */
#include "blapi.h" #include "blapi.h"
#include "sha256.h" /* for struct SHA256ContextStr */ #include "sha256.h" /* for struct SHA256ContextStr */
@ -1106,16 +1107,14 @@ SHA512_End(SHA512Context *ctx, unsigned char *digest,
{ {
#if defined(HAVE_LONG_LONG) #if defined(HAVE_LONG_LONG)
unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f; unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f;
unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf); PRUint64 t1;
PRUint64 lo, t1;
lo = (ctx->sizeLo << 3);
#else #else
unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f; unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
PRUint64 lo = ctx->sizeLo;
PRUint32 t1; PRUint32 t1;
lo.lo <<= 3;
#endif #endif
unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
PRUint64 lo;
LL_SHL(lo, ctx->sizeLo, 3);
SHA512_Update(ctx, pad, padLen); SHA512_Update(ctx, pad, padLen);

Просмотреть файл

@ -171,6 +171,7 @@ STUB_DECLARE(SECStatus,SECITEM_CopyItem_Util,(PRArenaPool *arena,
SECItem *to,const SECItem *from)); SECItem *to,const SECItem *from));
STUB_DECLARE(void,SECITEM_FreeItem_Util,(SECItem *zap, PRBool freeit)); STUB_DECLARE(void,SECITEM_FreeItem_Util,(SECItem *zap, PRBool freeit));
STUB_DECLARE(void,SECITEM_ZfreeItem_Util,(SECItem *zap, PRBool freeit)); STUB_DECLARE(void,SECITEM_ZfreeItem_Util,(SECItem *zap, PRBool freeit));
STUB_DECLARE(int, NSS_SecureMemcmp,(const void *a, const void *b, size_t n));
#define PORT_ZNew_stub(type) (type*)PORT_ZAlloc_stub(sizeof(type)) #define PORT_ZNew_stub(type) (type*)PORT_ZAlloc_stub(sizeof(type))
@ -482,6 +483,13 @@ SECITEM_ZfreeItem_stub(SECItem *zap, PRBool freeit)
abort(); abort();
} }
extern int
NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n)
{
STUB_SAFE_CALL3(NSS_SecureMemcmp, a, b, n);
abort();
}
#ifdef FREEBL_NO_WEAK #ifdef FREEBL_NO_WEAK
static const char *nsprLibName = SHLIB_PREFIX"nspr4."SHLIB_SUFFIX; static const char *nsprLibName = SHLIB_PREFIX"nspr4."SHLIB_SUFFIX;
@ -523,6 +531,7 @@ freebl_InitNSSUtil(void *lib)
STUB_FETCH_FUNCTION(SECITEM_CompareItem_Util); STUB_FETCH_FUNCTION(SECITEM_CompareItem_Util);
STUB_FETCH_FUNCTION(SECITEM_CopyItem_Util); STUB_FETCH_FUNCTION(SECITEM_CopyItem_Util);
STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util); STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util);
STUB_FETCH_FUNCTION(NSS_SecureMemcmp);
return SECSuccess; return SECSuccess;
} }

Просмотреть файл

@ -69,6 +69,8 @@
#define SECITEM_FreeItem SECITEM_FreeItem_stub #define SECITEM_FreeItem SECITEM_FreeItem_stub
#define SECITEM_ZfreeItem SECITEM_ZfreeItem_stub #define SECITEM_ZfreeItem SECITEM_ZfreeItem_stub
#define NSS_SecureMemcmp NSS_SecureMemcmp_stub
#define PR_Assert PR_Assert_stub #define PR_Assert PR_Assert_stub
#define PR_CallOnce PR_CallOnce_stub #define PR_CallOnce PR_CallOnce_stub
#define PR_Close PR_Close_stub #define PR_Close PR_Close_stub

Просмотреть файл

@ -610,8 +610,8 @@ PKIX_ERRORENTRY(INFOACCESSCREATELISTFAILED,pkix_pl_InfoAccess_CreateList failed,
PKIX_ERRORENTRY(INFOACCESSGETLOCATIONFAILED,PKIX_PL_InfoAccess_GetLocation failed,0), PKIX_ERRORENTRY(INFOACCESSGETLOCATIONFAILED,PKIX_PL_InfoAccess_GetLocation failed,0),
PKIX_ERRORENTRY(INFOACCESSGETLOCATIONTYPEFAILED,PKIX_PL_InfoAccess_GetLocationType failed,0), PKIX_ERRORENTRY(INFOACCESSGETLOCATIONTYPEFAILED,PKIX_PL_InfoAccess_GetLocationType failed,0),
PKIX_ERRORENTRY(INFOACCESSGETMETHODFAILED,PKIX_PL_InfoAccess_GetMethod failed,0), PKIX_ERRORENTRY(INFOACCESSGETMETHODFAILED,PKIX_PL_InfoAccess_GetMethod failed,0),
PKIX_ERRORENTRY(INFOACCESSPARSELOCATIONFAILED,pkix_pl_InfoAccess_ParseLocation failed,0), PKIX_ERRORENTRY(INFOACCESSPARSELOCATIONFAILED,pkix_pl_InfoAccess_ParseLocation failed,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
PKIX_ERRORENTRY(INFOACCESSPARSETOKENSFAILED,pkix_pl_InfoAccess_ParseTokens failed,0), PKIX_ERRORENTRY(INFOACCESSPARSETOKENSFAILED,pkix_pl_InfoAccess_ParseTokens failed,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
PKIX_ERRORENTRY(INITIALIZECHECKERSFAILED,pkix_InitializeCheckers failed,0), PKIX_ERRORENTRY(INITIALIZECHECKERSFAILED,pkix_InitializeCheckers failed,0),
PKIX_ERRORENTRY(INITIALIZEFAILED,PKIX_PL_Initialize failed,0), PKIX_ERRORENTRY(INITIALIZEFAILED,PKIX_PL_Initialize failed,0),
PKIX_ERRORENTRY(INPUTLISTMUSTBEHEADER,Input List must be header,SEC_ERROR_INVALID_ARGS), PKIX_ERRORENTRY(INPUTLISTMUSTBEHEADER,Input List must be header,SEC_ERROR_INVALID_ARGS),
@ -732,7 +732,7 @@ PKIX_ERRORENTRY(NORESPONSEDATAINHTTPRESPONSE,No responseData in Http Response,SE
PKIX_ERRORENTRY(NOTARGETCERTSUPPLIED,No target cert supplied,SEC_ERROR_INVALID_ARGS), PKIX_ERRORENTRY(NOTARGETCERTSUPPLIED,No target cert supplied,SEC_ERROR_INVALID_ARGS),
PKIX_ERRORENTRY(NOTCONFORMINGCRLDP,Cert CRL DP does not conform to the rfc, 0), PKIX_ERRORENTRY(NOTCONFORMINGCRLDP,Cert CRL DP does not conform to the rfc, 0),
PKIX_ERRORENTRY(NOTDERPACKAGE,Not a DER package,0), PKIX_ERRORENTRY(NOTDERPACKAGE,Not a DER package,0),
PKIX_ERRORENTRY(NOTENOUGHNAMECOMPONENTSINGENERALNAME,Not enough name components in GeneralName,0), PKIX_ERRORENTRY(NOTENOUGHNAMECOMPONENTSINGENERALNAME,Not enough name components in GeneralName,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
PKIX_ERRORENTRY(NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED,Failed to convert nss certificate usage to pkix ku and eku data structures,0), PKIX_ERRORENTRY(NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED,Failed to convert nss certificate usage to pkix ku and eku data structures,0),
PKIX_ERRORENTRY(NSSCONTEXTCREATEFAILED,PKIX_PL_NssContext_Create failed,0), PKIX_ERRORENTRY(NSSCONTEXTCREATEFAILED,PKIX_PL_NssContext_Create failed,0),
PKIX_ERRORENTRY(NSSCONTEXTDESTROYFAILED,PKIX_PL_NssContext_Destroy failed,0), PKIX_ERRORENTRY(NSSCONTEXTDESTROYFAILED,PKIX_PL_NssContext_Destroy failed,0),
@ -1071,7 +1071,6 @@ PKIX_ERRORENTRY(UNDEFINEDEQUALSCALLBACK,Undefined equals callback,0),
PKIX_ERRORENTRY(UNEXPECTEDERRORINESTABLISHINGCONNECTION,Unexpected error in establishing connection,0), PKIX_ERRORENTRY(UNEXPECTEDERRORINESTABLISHINGCONNECTION,Unexpected error in establishing connection,0),
PKIX_ERRORENTRY(UNEXPECTEDRESULTCODEINRESPONSE,Unexpected result code in Response,SEC_ERROR_BAD_LDAP_RESPONSE), PKIX_ERRORENTRY(UNEXPECTEDRESULTCODEINRESPONSE,Unexpected result code in Response,SEC_ERROR_BAD_LDAP_RESPONSE),
PKIX_ERRORENTRY(UNKNOWNFORMAT,Unknown format,SEC_ERROR_INVALID_ARGS), PKIX_ERRORENTRY(UNKNOWNFORMAT,Unknown format,SEC_ERROR_INVALID_ARGS),
PKIX_ERRORENTRY(UNKNOWNINFOACCESSTYPE,Unknown InfoAccess type,SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE),
PKIX_ERRORENTRY(UNKNOWNINFOACCESSMETHOD,Unknown InfoAccess method,SEC_ERROR_BAD_INFO_ACCESS_METHOD), PKIX_ERRORENTRY(UNKNOWNINFOACCESSMETHOD,Unknown InfoAccess method,SEC_ERROR_BAD_INFO_ACCESS_METHOD),
PKIX_ERRORENTRY(UNKNOWNOBJECTOID,Unknown object OID,0), PKIX_ERRORENTRY(UNKNOWNOBJECTOID,Unknown object OID,0),
PKIX_ERRORENTRY(UNKNOWNOBJECTTYPE,Unknown object type,0), PKIX_ERRORENTRY(UNKNOWNOBJECTTYPE,Unknown object type,0),

Просмотреть файл

@ -658,7 +658,8 @@ PKIX_PL_AIAMgr_GetAIACerts(
PKIX_AIAMGRGETLDAPCERTSFAILED); PKIX_AIAMGRGETLDAPCERTSFAILED);
} else { } else {
/* We only support http and ldap requests. */ /* We only support http and ldap requests. */
PKIX_ERROR(PKIX_UNKNOWNINFOACCESSTYPE); PKIX_DECREF(ia);
continue;
} }
if (nbio != NULL) { /* WOULDBLOCK */ if (nbio != NULL) { /* WOULDBLOCK */

Просмотреть файл

@ -849,7 +849,7 @@ DownloadCrl(pkix_pl_CrlDp *dp, PKIX_PL_CRL **crl,
location[uri->len] = 0; location[uri->len] = 0;
if (CERT_ParseURL(location, &hostname, if (CERT_ParseURL(location, &hostname,
&port, &path) != SECSuccess) { &port, &path) != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_INFO_ACCESS_LOCATION); PORT_SetError(SEC_ERROR_BAD_CRL_DP_URL);
savedError = PKIX_URLPARSINGFAILED; savedError = PKIX_URLPARSINGFAILED;
break; break;
} }
@ -859,7 +859,7 @@ DownloadCrl(pkix_pl_CrlDp *dp, PKIX_PL_CRL **crl,
if ((*hcv1->createSessionFcn)(hostname, port, if ((*hcv1->createSessionFcn)(hostname, port,
&pServerSession) != SECSuccess) { &pServerSession) != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_INFO_ACCESS_LOCATION); PORT_SetError(SEC_ERROR_BAD_CRL_DP_URL);
savedError = PKIX_URLPARSINGFAILED; savedError = PKIX_URLPARSINGFAILED;
break; break;
} }

Просмотреть файл

@ -1003,3 +1003,13 @@ CERT_GetConstrainedCertificateNames;
;+ local: ;+ local:
;+ *; ;+ *;
;+}; ;+};
;+NSS_3.12.9 { # NSS 3.12.9 release
;+ global:
CERT_FindCertByNicknameOrEmailAddrForUsage;
PK11_DeriveWithTemplate;
PK11_FindCertsFromEmailAddress;
PK11_KeyGenWithTemplate;
SECMOD_RestartModules;
;+ local:
;+ *;
;+};

Просмотреть файл

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
/* $Id: nss.h,v 1.81.2.2 2010/09/16 18:08:52 christophe.ravel.bugs%sun.com Exp $ */ /* $Id: nss.h,v 1.81.2.3 2010/09/23 17:07:52 christophe.ravel.bugs%sun.com Exp $ */
#ifndef __nss_h_ #ifndef __nss_h_
#define __nss_h_ #define __nss_h_
@ -66,12 +66,12 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/ */
#define NSS_VERSION "3.12.8.0" _NSS_ECC_STRING _NSS_CUSTOMIZED #define NSS_VERSION "3.12.9.0" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
#define NSS_VMAJOR 3 #define NSS_VMAJOR 3
#define NSS_VMINOR 12 #define NSS_VMINOR 12
#define NSS_VPATCH 8 #define NSS_VPATCH 9
#define NSS_VBUILD 0 #define NSS_VBUILD 0
#define NSS_BETA PR_FALSE #define NSS_BETA PR_TRUE
#ifndef RC_INVOKED #ifndef RC_INVOKED

Просмотреть файл

@ -653,6 +653,82 @@ loser:
return NULL; return NULL;
} }
/* Traverse slots callback */
typedef struct FindCertsEmailArgStr {
char *email;
CERTCertList *certList;
} FindCertsEmailArg;
SECStatus
FindCertsEmailCallback(CERTCertificate *cert, SECItem *item, void *arg)
{
FindCertsEmailArg *cbparam = (FindCertsEmailArg *) arg;
const char *cert_email = CERT_GetFirstEmailAddress(cert);
PRBool found = PR_FALSE;
/* Email address present in certificate? */
if (cert_email == NULL){
return SECSuccess;
}
/* Parameter correctly set? */
if (cbparam->email == NULL) {
return SECFailure;
}
/* Loop over all email addresses */
do {
if (!strcmp(cert_email, cbparam->email)) {
/* found one matching email address */
PRTime now = PR_Now();
found = PR_TRUE;
CERT_AddCertToListSorted(cbparam->certList,
CERT_DupCertificate(cert),
CERT_SortCBValidity, &now);
}
cert_email = CERT_GetNextEmailAddress(cert, cert_email);
} while (cert_email && !found);
return SECSuccess;
}
/* Find all certificates with matching email address */
CERTCertList *
PK11_FindCertsFromEmailAddress(const char *email, void *wincx)
{
FindCertsEmailArg cbparam;
SECStatus rv;
cbparam.certList = CERT_NewCertList();
if (cbparam.certList == NULL) {
return NULL;
}
cbparam.email = CERT_FixupEmailAddr(email);
if (cbparam.email == NULL) {
CERT_DestroyCertList(cbparam.certList);
return NULL;
}
rv = PK11_TraverseSlotCerts(FindCertsEmailCallback, &cbparam, NULL);
if (rv != SECSuccess) {
CERT_DestroyCertList(cbparam.certList);
PORT_Free(cbparam.email);
return NULL;
}
/* empty list? */
if (CERT_LIST_HEAD(cbparam.certList) == NULL ||
CERT_LIST_END(CERT_LIST_HEAD(cbparam.certList), cbparam.certList)) {
CERT_DestroyCertList(cbparam.certList);
cbparam.certList = NULL;
}
PORT_Free(cbparam.email);
return cbparam.certList;
}
CERTCertList * CERTCertList *
PK11_FindCertsFromNickname(const char *nickname, void *wincx) PK11_FindCertsFromNickname(const char *nickname, void *wincx)
{ {

Просмотреть файл

@ -334,6 +334,19 @@ PK11SymKey *PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot,
CK_MECHANISM_TYPE type, SECItem *param, CK_MECHANISM_TYPE type, SECItem *param,
int keySize, SECItem *keyid, CK_FLAGS opFlags, int keySize, SECItem *keyid, CK_FLAGS opFlags,
PK11AttrFlags attrFlags, void *wincx); PK11AttrFlags attrFlags, void *wincx);
/* Generates a key using the exact template supplied by the caller. The other
* PK11_[Token]KeyGen mechanisms should be used instead of this one whenever
* they work because they include/exclude the CKA_VALUE_LEN template value
* based on the mechanism type as required by many tokens.
*
* keyGenType should be PK11_GetKeyGenWithSize(type, <key size>) or it should
* be equal to type if PK11_GetKeyGenWithSize cannot be used (e.g. because
* pk11wrap does not know about the mechanisms).
*/
PK11SymKey *PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_MECHANISM_TYPE keyGenType,
SECItem *param, CK_ATTRIBUTE * attrs,
unsigned int attrsCount, void *wincx);
PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname,
void *wincx); void *wincx);
PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey); PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey);
@ -403,6 +416,12 @@ PK11SymKey * PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey,
CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE derive,
SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
int keySize, CK_FLAGS flags, PRBool isPerm); int keySize, CK_FLAGS flags, PRBool isPerm);
PK11SymKey *
PK11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs,
PRBool isPerm);
PK11SymKey *PK11_PubDerive( SECKEYPrivateKey *privKey, PK11SymKey *PK11_PubDerive( SECKEYPrivateKey *privKey,
SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB, SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB,
@ -604,6 +623,7 @@ SECStatus PK11_TraverseSlotCerts(
SECStatus(* callback)(CERTCertificate*,SECItem *,void *), SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
void *arg, void *wincx); void *arg, void *wincx);
CERTCertificate * PK11_FindCertFromNickname(const char *nickname, void *wincx); CERTCertificate * PK11_FindCertFromNickname(const char *nickname, void *wincx);
CERTCertList * PK11_FindCertsFromEmailAddress(const char *email, void *wincx);
CERTCertList * PK11_FindCertsFromNickname(const char *nickname, void *wincx); CERTCertList * PK11_FindCertsFromNickname(const char *nickname, void *wincx);
CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey); CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey);
SECStatus PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, SECStatus PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,

Просмотреть файл

@ -52,12 +52,6 @@
#include "secerr.h" #include "secerr.h"
#include "hasht.h" #include "hasht.h"
/* forward static declarations. */
static PK11SymKey *pk11_DeriveWithTemplate(PK11SymKey *baseKey,
CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation, int keySize, CK_ATTRIBUTE *userAttr,
unsigned int numAttrs, PRBool isPerm);
static void static void
pk11_EnterKeyMonitor(PK11SymKey *symKey) { pk11_EnterKeyMonitor(PK11SymKey *symKey) {
if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe)) if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))
@ -921,7 +915,7 @@ pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_ATTRIBUTE *attrs = genTemplate; CK_ATTRIBUTE *attrs = genTemplate;
int count = sizeof(genTemplate)/sizeof(genTemplate[0]); int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
CK_SESSION_HANDLE session; CK_SESSION_HANDLE session;
CK_MECHANISM mechanism; CK_MECHANISM_TYPE keyGenType;
CK_RV crv; CK_RV crv;
CK_BBOOL cktrue = CK_TRUE; CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL ckfalse = CK_FALSE; CK_BBOOL ckfalse = CK_FALSE;
@ -957,76 +951,16 @@ pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
count = attrs - genTemplate; count = attrs - genTemplate;
PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
/* Initialize the Key Gen Mechanism */ keyGenType = PK11_GetKeyGenWithSize(type, keySize);
mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize); if (keyGenType == CKM_FAKE_RANDOM) {
if (mechanism.mechanism == CKM_FAKE_RANDOM) { PORT_SetError( SEC_ERROR_NO_MODULE );
PORT_SetError( SEC_ERROR_NO_MODULE ); return NULL;
return NULL;
} }
symKey = PK11_KeyGenWithTemplate(slot, type, keyGenType,
/* find a slot to generate the key into */ param, genTemplate, count, wincx);
/* Only do slot management if this is not a token key */ if (symKey != NULL) {
if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) { symKey->size = keySize;
PK11SlotInfo *bestSlot;
bestSlot = PK11_GetBestSlot(type,wincx);
if (bestSlot == NULL) {
PORT_SetError( SEC_ERROR_NO_MODULE );
return NULL;
}
symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx);
PK11_FreeSlot(bestSlot);
} else {
symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
} }
if (symKey == NULL) return NULL;
symKey->size = keySize;
symKey->origin = PK11_OriginGenerated;
/* Set the parameters for the key gen if provided */
mechanism.pParameter = NULL;
mechanism.ulParameterLen = 0;
if (param) {
mechanism.pParameter = param->data;
mechanism.ulParameterLen = param->len;
}
/* Get session and perform locking */
if (isToken) {
PK11_Authenticate(symKey->slot,PR_TRUE,wincx);
/* Should always be original slot */
session = PK11_GetRWSession(symKey->slot);
symKey->owner = PR_FALSE;
} else {
session = symKey->session;
if (session != CK_INVALID_SESSION)
pk11_EnterKeyMonitor(symKey);
}
if (session == CK_INVALID_SESSION) {
PK11_FreeSymKey(symKey);
PORT_SetError(SEC_ERROR_BAD_DATA);
return NULL;
}
crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
&mechanism, genTemplate, count, &symKey->objectID);
/* Release lock and session */
if (isToken) {
PK11_RestoreROSession(symKey->slot, session);
} else {
pk11_ExitKeyMonitor(symKey);
}
if (crv != CKR_OK) {
PK11_FreeSymKey(symKey);
PORT_SetError( PK11_MapError(crv) );
return NULL;
}
return symKey; return symKey;
} }
@ -1098,6 +1032,107 @@ PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx); return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx);
} }
PK11SymKey *
PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_MECHANISM_TYPE keyGenType,
SECItem *param, CK_ATTRIBUTE * attrs,
unsigned int attrsCount, void *wincx)
{
PK11SymKey *symKey;
CK_SESSION_HANDLE session;
CK_MECHANISM mechanism;
CK_RV crv;
PRBool isToken = CK_FALSE;
CK_ULONG keySize = 0;
unsigned i;
/* Extract the template's CKA_VALUE_LEN into keySize and CKA_TOKEN into
isToken. */
for (i = 0; i < attrsCount; ++i) {
switch (attrs[i].type) {
case CKA_VALUE_LEN:
if (attrs[i].pValue == NULL ||
attrs[i].ulValueLen != sizeof(CK_ULONG)) {
PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT));
return NULL;
}
keySize = * (CK_ULONG *) attrs[i].pValue;
break;
case CKA_TOKEN:
if (attrs[i].pValue == NULL ||
attrs[i].ulValueLen != sizeof(CK_BBOOL)) {
PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT));
return NULL;
}
isToken = (*(CK_BBOOL*)attrs[i].pValue) ? PR_TRUE : PR_FALSE;
break;
}
}
/* find a slot to generate the key into */
/* Only do slot management if this is not a token key */
if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) {
PK11SlotInfo *bestSlot = PK11_GetBestSlot(type,wincx);
if (bestSlot == NULL) {
PORT_SetError( SEC_ERROR_NO_MODULE );
return NULL;
}
symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx);
PK11_FreeSlot(bestSlot);
} else {
symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
}
if (symKey == NULL) return NULL;
symKey->size = keySize;
symKey->origin = PK11_OriginGenerated;
/* Set the parameters for the key gen if provided */
mechanism.mechanism = keyGenType;
mechanism.pParameter = NULL;
mechanism.ulParameterLen = 0;
if (param) {
mechanism.pParameter = param->data;
mechanism.ulParameterLen = param->len;
}
/* Get session and perform locking */
if (isToken) {
PK11_Authenticate(symKey->slot,PR_TRUE,wincx);
/* Should always be original slot */
session = PK11_GetRWSession(symKey->slot);
symKey->owner = PR_FALSE;
} else {
session = symKey->session;
if (session != CK_INVALID_SESSION)
pk11_EnterKeyMonitor(symKey);
}
if (session == CK_INVALID_SESSION) {
PK11_FreeSymKey(symKey);
PORT_SetError(SEC_ERROR_BAD_DATA);
return NULL;
}
crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
&mechanism, attrs, attrsCount, &symKey->objectID);
/* Release lock and session */
if (isToken) {
PK11_RestoreROSession(symKey->slot, session);
} else {
pk11_ExitKeyMonitor(symKey);
}
if (crv != CKR_OK) {
PK11_FreeSymKey(symKey);
PORT_SetError( PK11_MapError(crv) );
return NULL;
}
return symKey;
}
/* --- */ /* --- */
PK11SymKey * PK11SymKey *
PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx) PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx)
@ -1368,7 +1403,7 @@ PK11_Derive( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
int keySize) int keySize)
{ {
return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
keySize, NULL, 0, PR_FALSE); keySize, NULL, 0, PR_FALSE);
} }
@ -1383,7 +1418,7 @@ PK11_DeriveWithFlags( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
unsigned int templateCount; unsigned int templateCount;
templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue); templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
keySize, keyTemplate, templateCount, PR_FALSE); keySize, keyTemplate, templateCount, PR_FALSE);
} }
@ -1403,12 +1438,12 @@ PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
} }
templateCount = attrs - keyTemplate; templateCount = attrs - keyTemplate;
templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue); templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
keySize, keyTemplate, templateCount, isPerm); keySize, keyTemplate, templateCount, isPerm);
} }
static PK11SymKey * PK11SymKey *
pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, PK11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs,
PRBool isPerm) PRBool isPerm)

Просмотреть файл

@ -1504,3 +1504,82 @@ SECMOD_CloseUserDB(PK11SlotInfo *slot)
PR_smprintf_free(sendSpec); PR_smprintf_free(sendSpec);
return rv; return rv;
} }
/*
* Restart PKCS #11 modules after a fork(). See secmod.h for more information.
*/
SECStatus
SECMOD_RestartModules(PRBool force)
{
SECMODModuleList *mlp;
SECStatus rrv = SECSuccess;
int lastError = 0;
if (!moduleLock) {
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return SECFailure;
}
/* Only need to restart the PKCS #11 modules that were initialized */
SECMOD_GetReadLock(moduleLock);
for (mlp = modules; mlp != NULL; mlp = mlp->next) {
SECMODModule *mod = mlp->module;
CK_ULONG count;
SECStatus rv;
int i;
/* If the module needs to be reset, do so */
if (force || (PK11_GETTAB(mod)->
C_GetSlotList(CK_FALSE, NULL, &count) != CKR_OK)) {
PRBool alreadyLoaded;
/* first call Finalize. This is not required by PKCS #11, but some
* older modules require it, and it doesn't hurt (compliant modules
* will return CKR_NOT_INITIALIZED */
(void) PK11_GETTAB(mod)->C_Finalize(NULL);
/* now initialize the module, this function reinitializes
* a module in place, preserving existing slots (even if they
* no longer exist) */
rv = secmod_ModuleInit(mod, NULL, &alreadyLoaded);
if (rv != SECSuccess) {
/* save the last error code */
lastError = PORT_GetError();
rrv = rv;
/* couldn't reinit the module, disable all its slots */
for (i=0; i < mod->slotCount; i++) {
mod->slots[i]->disabled = PR_TRUE;
mod->slots[i]->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
}
continue;
}
for (i=0; i < mod->slotCount; i++) {
/* get new token sessions, bump the series up so that
* we refresh other old sessions. This will tell much of
* NSS to flush cached handles it may hold as well */
rv = PK11_InitToken(mod->slots[i],PR_TRUE);
/* PK11_InitToken could fail if the slot isn't present.
* If it is present, though, something is wrong and we should
* disable the slot and let the caller know. */
if (rv != SECSuccess && PK11_IsPresent(mod->slots[i])) {
/* save the last error code */
lastError = PORT_GetError();
rrv = rv;
/* disable the token */
mod->slots[i]->disabled = PR_TRUE;
mod->slots[i]->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
}
}
}
}
SECMOD_ReleaseReadLock(moduleLock);
/*
* on multiple failures, we are only returning the lastError. The caller
* can determine which slots are bad by calling PK11_IsDisabled().
*/
if (rrv != SECSuccess) {
/* restore the last error code */
PORT_SetError(lastError);
}
return rrv;
}

Просмотреть файл

@ -95,6 +95,18 @@ SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
SECMODModule * SECMOD_CreateModule(const char *lib, const char *name, SECMODModule * SECMOD_CreateModule(const char *lib, const char *name,
const char *param, const char *nss); const char *param, const char *nss);
/*
* After a fork(), PKCS #11 says we need to call C_Initialize again in
* the child before we can use the module. This function causes this
* reinitialization.
* NOTE: Any outstanding handles will become invalid, which means your
* keys and contexts will fail, but new ones can be created.
*
* Setting 'force' to true means to do the reinitialization even if the
* PKCS #11 module does not seem to need it. This allows software modules
* which ignore fork to preserve their keys across the fork().
*/
SECStatus SECMOD_RestartModules(PRBool force);
/* Module Management */ /* Module Management */

Просмотреть файл

@ -0,0 +1,396 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Mozilla Fonudation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "seccomon.h"
#include "secerr.h"
#include "blapi.h"
#include "pkcs11i.h"
#include "softoken.h"
static CK_RV
jpake_mapStatus(SECStatus rv, CK_RV invalidArgsMapping) {
int err;
if (rv == SECSuccess)
return CKR_OK;
err = PORT_GetError();
switch (err) {
/* XXX: SEC_ERROR_INVALID_ARGS might be caused by invalid template
parameters. */
case SEC_ERROR_INVALID_ARGS: return invalidArgsMapping;
case SEC_ERROR_BAD_SIGNATURE: return CKR_SIGNATURE_INVALID;
case SEC_ERROR_NO_MEMORY: return CKR_HOST_MEMORY;
}
return CKR_FUNCTION_FAILED;
}
/* If key is not NULL then the gx value will be stored as an attribute with
the type given by the gxAttrType parameter. */
static CK_RV
jpake_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
const SECItem * signerID, const SECItem * x,
CK_NSS_JPAKEPublicValue * out)
{
SECItem gx, gv, r;
CK_RV crv;
PORT_Assert(arena != NULL);
gx.data = NULL;
gv.data = NULL;
r.data = NULL;
crv = jpake_mapStatus(JPAKE_Sign(arena, pqg, hashType, signerID, x, NULL,
NULL, &gx, &gv, &r),
CKR_MECHANISM_PARAM_INVALID);
if (crv == CKR_OK) {
if (out->pGX != NULL && out->ulGXLen >= gx.len ||
out->pGV != NULL && out->ulGVLen >= gv.len ||
out->pR != NULL && out->ulRLen >= r.len) {
PORT_Memcpy(out->pGX, gx.data, gx.len);
PORT_Memcpy(out->pGV, gv.data, gv.len);
PORT_Memcpy(out->pR, r.data, r.len);
out->ulGXLen = gx.len;
out->ulGVLen = gv.len;
out->ulRLen = r.len;
} else {
crv = CKR_MECHANISM_PARAM_INVALID;
}
}
return crv;
}
static CK_RV
jpake_Verify(PLArenaPool * arena, const PQGParams * pqg,
HASH_HashType hashType, const SECItem * signerID,
const CK_BYTE * peerIDData, CK_ULONG peerIDLen,
const CK_NSS_JPAKEPublicValue * publicValueIn)
{
SECItem peerID, gx, gv, r;
peerID.data = (unsigned char *) peerIDData; peerID.len = peerIDLen;
gx.data = publicValueIn->pGX; gx.len = publicValueIn->ulGXLen;
gv.data = publicValueIn->pGV; gv.len = publicValueIn->ulGVLen;
r.data = publicValueIn->pR; r.len = publicValueIn->ulRLen;
return jpake_mapStatus(JPAKE_Verify(arena, pqg, hashType, signerID, &peerID,
&gx, &gv, &r),
CKR_MECHANISM_PARAM_INVALID);
}
#define NUM_ELEM(x) (sizeof (x) / sizeof (x)[0])
/* Ensure that the key is of the given type. */
static CK_RV
jpake_ensureKeyType(SFTKObject * key, CK_KEY_TYPE keyType)
{
CK_RV crv;
SFTKAttribute * keyTypeAttr = sftk_FindAttribute(key, CKA_KEY_TYPE);
crv = keyTypeAttr != NULL &&
*(CK_KEY_TYPE *)keyTypeAttr->attrib.pValue == keyType
? CKR_OK
: CKR_TEMPLATE_INCONSISTENT;
if (keyTypeAttr != NULL)
sftk_FreeAttribute(keyTypeAttr);
return crv;
}
/* If the template has the key type set, ensure that it was set to the correct
* value. If the template did not have the key type set, set it to the
* correct value.
*/
static CK_RV
jpake_enforceKeyType(SFTKObject * key, CK_KEY_TYPE keyType) {
CK_RV crv;
SFTKAttribute * keyTypeAttr = sftk_FindAttribute(key, CKA_KEY_TYPE);
if (keyTypeAttr != NULL) {
crv = *(CK_KEY_TYPE *)keyTypeAttr->attrib.pValue == keyType
? CKR_OK
: CKR_TEMPLATE_INCONSISTENT;
sftk_FreeAttribute(keyTypeAttr);
} else {
crv = sftk_forceAttribute(key, CKA_KEY_TYPE, &keyType, sizeof keyType);
}
return crv;
}
static CK_RV
jpake_MultipleSecItem2Attribute(SFTKObject * key, const SFTKItemTemplate * attrs,
size_t attrsCount)
{
size_t i;
for (i = 0; i < attrsCount; ++i) {
CK_RV crv = sftk_forceAttribute(key, attrs[i].type, attrs[i].item->data,
attrs[i].item->len);
if (crv != CKR_OK)
return crv;
}
return CKR_OK;
}
CK_RV
jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params * params,
SFTKObject * key)
{
CK_RV crv;
PQGParams pqg;
PLArenaPool * arena;
SECItem signerID;
SFTKItemTemplate templateAttrs[] = {
{ CKA_PRIME, &pqg.prime },
{ CKA_SUBPRIME, &pqg.subPrime },
{ CKA_BASE, &pqg.base },
{ CKA_NSS_JPAKE_SIGNERID, &signerID }
};
SECItem x2, gx1, gx2;
const SFTKItemTemplate generatedAttrs[] = {
{ CKA_NSS_JPAKE_X2, &x2 },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
};
SECItem x1;
PORT_Assert(params != NULL);
PORT_Assert(key != NULL);
arena = PORT_NewArena(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE);
if (arena == NULL)
crv = CKR_HOST_MEMORY;
crv = sftk_MultipleAttribute2SecItem(arena, key, templateAttrs,
NUM_ELEM(templateAttrs));
if (crv == CKR_OK && (signerID.data == NULL || signerID.len == 0))
crv = CKR_TEMPLATE_INCOMPLETE;
/* generate x1, g^x1 and the proof of knowledge of x1 */
if (crv == CKR_OK) {
x1.data = NULL;
crv = jpake_mapStatus(DSA_NewRandom(arena, &pqg.subPrime, &x1),
CKR_TEMPLATE_INCONSISTENT);
}
if (crv == CKR_OK)
crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x1, &params->gx1);
/* generate x2, g^x2 and the proof of knowledge of x2 */
if (crv == CKR_OK) {
x2.data = NULL;
crv = jpake_mapStatus(DSA_NewRandom(arena, &pqg.subPrime, &x2),
CKR_TEMPLATE_INCONSISTENT);
}
if (crv == CKR_OK)
crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x2, &params->gx2);
/* Save the values needed for round 2 into CKA_VALUE */
if (crv == CKR_OK) {
gx1.data = params->gx1.pGX;
gx1.len = params->gx1.ulGXLen;
gx2.data = params->gx2.pGX;
gx2.len = params->gx2.ulGXLen;
crv = jpake_MultipleSecItem2Attribute(key, generatedAttrs,
NUM_ELEM(generatedAttrs));
}
PORT_FreeArena(arena, PR_TRUE);
return crv;
}
CK_RV
jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params * params,
SFTKObject * sourceKey, SFTKObject * key)
{
CK_RV crv;
PLArenaPool * arena;
PQGParams pqg;
SECItem signerID, x2, gx1, gx2;
SFTKItemTemplate sourceAttrs[] = {
{ CKA_PRIME, &pqg.prime },
{ CKA_SUBPRIME, &pqg.subPrime },
{ CKA_BASE, &pqg.base },
{ CKA_NSS_JPAKE_SIGNERID, &signerID },
{ CKA_NSS_JPAKE_X2, &x2 },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
};
SECItem x2s, gx3, gx4;
const SFTKItemTemplate copiedAndGeneratedAttrs[] = {
{ CKA_NSS_JPAKE_SIGNERID, &signerID },
{ CKA_PRIME, &pqg.prime },
{ CKA_SUBPRIME, &pqg.subPrime },
{ CKA_NSS_JPAKE_X2, &x2 },
{ CKA_NSS_JPAKE_X2S, &x2s },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
{ CKA_NSS_JPAKE_GX3, &gx3 },
{ CKA_NSS_JPAKE_GX4, &gx4 }
};
SECItem peerID;
PORT_Assert(params != NULL);
PORT_Assert(sourceKey != NULL);
PORT_Assert(key != NULL);
arena = PORT_NewArena(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE);
if (arena == NULL)
crv = CKR_HOST_MEMORY;
/* TODO: check CKK_NSS_JPAKE_ROUND1 */
crv = sftk_MultipleAttribute2SecItem(arena, sourceKey, sourceAttrs,
NUM_ELEM(sourceAttrs));
/* Get the peer's ID out of the template and sanity-check it. */
if (crv == CKR_OK)
crv = sftk_Attribute2SecItem(arena, &peerID, key,
CKA_NSS_JPAKE_PEERID);
if (crv == CKR_OK && (peerID.data == NULL || peerID.len == 0))
crv = CKR_TEMPLATE_INCOMPLETE;
if (crv == CKR_OK && SECITEM_CompareItem(&signerID, &peerID) == SECEqual)
crv = CKR_TEMPLATE_INCONSISTENT;
/* Verify zero-knowledge proofs for g^x3 and g^x4 */
if (crv == CKR_OK)
crv = jpake_Verify(arena, &pqg, hashType, &signerID,
peerID.data, peerID.len, &params->gx3);
if (crv == CKR_OK)
crv = jpake_Verify(arena, &pqg, hashType, &signerID,
peerID.data, peerID.len, &params->gx4);
/* Calculate the base and x2s for A=base^x2s */
if (crv == CKR_OK) {
SECItem s;
s.data = params->pSharedKey;
s.len = params->ulSharedKeyLen;
gx3.data = params->gx3.pGX;
gx3.len = params->gx3.ulGXLen;
gx4.data = params->gx4.pGX;
gx4.len = params->gx4.ulGXLen;
pqg.base.data = NULL;
x2s.data = NULL;
crv = jpake_mapStatus(JPAKE_Round2(arena, &pqg.prime, &pqg.subPrime,
&gx1, &gx3, &gx4, &pqg.base,
&x2, &s, &x2s),
CKR_MECHANISM_PARAM_INVALID);
}
/* Generate A=base^x2s and its zero-knowledge proof. */
if (crv == CKR_OK)
crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x2s, &params->A);
/* Copy P and Q from the ROUND1 key to the ROUND2 key and save the values
needed for the final key material derivation into CKA_VALUE. */
if (crv == CKR_OK)
crv = sftk_forceAttribute(key, CKA_PRIME, pqg.prime.data,
pqg.prime.len);
if (crv == CKR_OK)
crv = sftk_forceAttribute(key, CKA_SUBPRIME, pqg.subPrime.data,
pqg.subPrime.len);
if (crv == CKR_OK) {
crv = jpake_MultipleSecItem2Attribute(key, copiedAndGeneratedAttrs,
NUM_ELEM(copiedAndGeneratedAttrs));
}
if (crv == CKR_OK)
crv = jpake_enforceKeyType(key, CKK_NSS_JPAKE_ROUND2);
PORT_FreeArena(arena, PR_TRUE);
return crv;
}
CK_RV
jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams * param,
SFTKObject * sourceKey, SFTKObject * key)
{
PLArenaPool * arena;
SECItem K;
PQGParams pqg;
CK_RV crv;
SECItem peerID, signerID, x2s, x2, gx1, gx2, gx3, gx4;
SFTKItemTemplate sourceAttrs[] = {
{ CKA_NSS_JPAKE_PEERID, &peerID },
{ CKA_NSS_JPAKE_SIGNERID, &signerID },
{ CKA_PRIME, &pqg.prime },
{ CKA_SUBPRIME, &pqg.subPrime },
{ CKA_NSS_JPAKE_X2, &x2 },
{ CKA_NSS_JPAKE_X2S, &x2s },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
{ CKA_NSS_JPAKE_GX3, &gx3 },
{ CKA_NSS_JPAKE_GX4, &gx4 }
};
PORT_Assert(param != NULL);
PORT_Assert(sourceKey != NULL);
PORT_Assert(key != NULL);
arena = PORT_NewArena(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE);
if (arena == NULL)
crv = CKR_HOST_MEMORY;
/* TODO: verify key type CKK_NSS_JPAKE_ROUND2 */
crv = sftk_MultipleAttribute2SecItem(arena, sourceKey, sourceAttrs,
NUM_ELEM(sourceAttrs));
/* Calculate base for B=base^x4s */
if (crv == CKR_OK) {
pqg.base.data = NULL;
crv = jpake_mapStatus(JPAKE_Round2(arena, &pqg.prime, &pqg.subPrime,
&gx1, &gx2, &gx3, &pqg.base,
NULL, NULL, NULL),
CKR_MECHANISM_PARAM_INVALID);
}
/* Verify zero-knowledge proof for B */
if (crv == CKR_OK)
crv = jpake_Verify(arena, &pqg, hashType, &signerID,
peerID.data, peerID.len, &param->B);
if (crv == CKR_OK) {
SECItem B;
B.data = param->B.pGX;
B.len = param->B.ulGXLen;
K.data = NULL;
crv = jpake_mapStatus(JPAKE_Final(arena, &pqg.prime, &pqg.subPrime,
&x2, &gx4, &x2s, &B, &K),
CKR_MECHANISM_PARAM_INVALID);
}
/* Save key material into CKA_VALUE. */
if (crv == CKR_OK)
crv = sftk_forceAttribute(key, CKA_VALUE, K.data, K.len);
if (crv == CKR_OK)
crv = jpake_enforceKeyType(key, CKK_GENERIC_SECRET);
PORT_FreeArena(arena, PR_TRUE);
return crv;
}

Просмотреть файл

@ -714,7 +714,7 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
crv = lg_GetULongAttribute(CKA_CLASS,&pTemplate[i],1, &objectClass); crv = lg_GetULongAttribute(CKA_CLASS,&pTemplate[i],1, &objectClass);
if (crv != CKR_OK) { if (crv != CKR_OK) {
classFlags = 0; classFlags = 0;
break;; break;
} }
switch (objectClass) { switch (objectClass) {
case CKO_CERTIFICATE: case CKO_CERTIFICATE:
@ -746,6 +746,7 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
case CKA_PRIVATE: case CKA_PRIVATE:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
classFlags = 0; classFlags = 0;
break;
} }
if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) { if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
classFlags &= (LG_PRIVATE|LG_KEY); classFlags &= (LG_PRIVATE|LG_KEY);
@ -756,6 +757,7 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
case CKA_SENSITIVE: case CKA_SENSITIVE:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
classFlags = 0; classFlags = 0;
break;
} }
if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) { if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
classFlags &= (LG_PRIVATE|LG_KEY); classFlags &= (LG_PRIVATE|LG_KEY);
@ -766,6 +768,7 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
case CKA_TOKEN: case CKA_TOKEN:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
classFlags = 0; classFlags = 0;
break;
} }
if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) { if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) {
classFlags = 0; classFlags = 0;
@ -778,9 +781,11 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
classFlags &= LG_TRUST; classFlags &= LG_TRUST;
copy = &cert_md5_hash; break; copy = &cert_md5_hash; break;
case CKA_CERTIFICATE_TYPE: case CKA_CERTIFICATE_TYPE:
crv = lg_GetULongAttribute(CKA_CLASS,&pTemplate[i],1,&certType); crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE,&pTemplate[i],
1,&certType);
if (crv != CKR_OK) { if (crv != CKR_OK) {
classFlags = 0; classFlags = 0;
break;
} }
classFlags &= LG_CERT; classFlags &= LG_CERT;
if (certType != CKC_X_509) { if (certType != CKC_X_509) {
@ -794,6 +799,7 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
case CKA_NETSCAPE_KRL: case CKA_NETSCAPE_KRL:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
classFlags = 0; classFlags = 0;
break;
} }
classFlags &= LG_CRL; classFlags &= LG_CRL;
isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE); isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE);

Просмотреть файл

@ -89,6 +89,7 @@ CSRCS = \
sftkpwd.c \ sftkpwd.c \
softkver.c \ softkver.c \
tlsprf.c \ tlsprf.c \
jpakesftk.c \
$(NULL) $(NULL)
ifdef SQLITE_UNSAFE_THREADS ifdef SQLITE_UNSAFE_THREADS

Просмотреть файл

@ -407,6 +407,11 @@ static const struct mechanismList mechanisms[] = {
{CKM_SHA512_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE}, {CKM_SHA512_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
{CKM_SHA512_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, {CKM_SHA512_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
{CKM_TLS_PRF_GENERAL, {0, 512, CKF_SN_VR}, PR_FALSE}, {CKM_TLS_PRF_GENERAL, {0, 512, CKF_SN_VR}, PR_FALSE},
/* ------------------------- HKDF Operations -------------------------- */
{CKM_NSS_HKDF_SHA1, {1, 128, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_HKDF_SHA256, {1, 128, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_HKDF_SHA384, {1, 128, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_HKDF_SHA512, {1, 128, CKF_DERIVE}, PR_TRUE},
/* ------------------------- CAST Operations --------------------------- */ /* ------------------------- CAST Operations --------------------------- */
#ifdef NSS_SOFTOKEN_DOES_CAST #ifdef NSS_SOFTOKEN_DOES_CAST
/* Cast operations are not supported ( yet? ) */ /* Cast operations are not supported ( yet? ) */
@ -487,6 +492,19 @@ static const struct mechanismList mechanisms[] = {
/* ------------------ AES Key Wrap (also encrypt) ------------------- */ /* ------------------ AES Key Wrap (also encrypt) ------------------- */
{CKM_NETSCAPE_AES_KEY_WRAP, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, {CKM_NETSCAPE_AES_KEY_WRAP, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
{CKM_NETSCAPE_AES_KEY_WRAP_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, {CKM_NETSCAPE_AES_KEY_WRAP_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
/* --------------------------- J-PAKE -------------------------------- */
{CKM_NSS_JPAKE_ROUND1_SHA1, {0, 0, CKF_GENERATE}, PR_TRUE},
{CKM_NSS_JPAKE_ROUND1_SHA256, {0, 0, CKF_GENERATE}, PR_TRUE},
{CKM_NSS_JPAKE_ROUND1_SHA384, {0, 0, CKF_GENERATE}, PR_TRUE},
{CKM_NSS_JPAKE_ROUND1_SHA512, {0, 0, CKF_GENERATE}, PR_TRUE},
{CKM_NSS_JPAKE_ROUND2_SHA1, {0, 0, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_JPAKE_ROUND2_SHA256, {0, 0, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_JPAKE_ROUND2_SHA384, {0, 0, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_JPAKE_ROUND2_SHA512, {0, 0, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_JPAKE_FINAL_SHA1, {0, 0, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_JPAKE_FINAL_SHA256, {0, 0, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_JPAKE_FINAL_SHA384, {0, 0, CKF_DERIVE}, PR_TRUE},
{CKM_NSS_JPAKE_FINAL_SHA512, {0, 0, CKF_DERIVE}, PR_TRUE}
}; };
static const CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]); static const CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
@ -969,6 +987,9 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
static NSSLOWKEYPrivateKey * static NSSLOWKEYPrivateKey *
sftk_mkPrivKey(SFTKObject *object,CK_KEY_TYPE key, CK_RV *rvp); sftk_mkPrivKey(SFTKObject *object,CK_KEY_TYPE key, CK_RV *rvp);
static SECStatus
sftk_fillRSAPrivateKey(SFTKObject *object);
/* /*
* check the consistancy and initialize a Private Key Object * check the consistancy and initialize a Private Key Object
*/ */
@ -982,35 +1003,60 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
CK_BBOOL wrap = CK_TRUE; CK_BBOOL wrap = CK_TRUE;
CK_BBOOL derive = CK_TRUE; CK_BBOOL derive = CK_TRUE;
CK_BBOOL ckfalse = CK_FALSE; CK_BBOOL ckfalse = CK_FALSE;
PRBool createObjectInfo = PR_TRUE;
int missing_rsa_mod_component = 0;
int missing_rsa_exp_component = 0;
int missing_rsa_crt_component = 0;
SECItem mod; SECItem mod;
CK_RV crv; CK_RV crv;
switch (key_type) { switch (key_type) {
case CKK_RSA: case CKK_RSA:
if ( !sftk_hasAttribute(object, CKA_MODULUS)) { if ( !sftk_hasAttribute(object, CKA_MODULUS)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_mod_component++;
} }
if ( !sftk_hasAttribute(object, CKA_PUBLIC_EXPONENT)) { if ( !sftk_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_exp_component++;
} }
if ( !sftk_hasAttribute(object, CKA_PRIVATE_EXPONENT)) { if ( !sftk_hasAttribute(object, CKA_PRIVATE_EXPONENT)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_exp_component++;
} }
if ( !sftk_hasAttribute(object, CKA_PRIME_1)) { if ( !sftk_hasAttribute(object, CKA_PRIME_1)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_mod_component++;
} }
if ( !sftk_hasAttribute(object, CKA_PRIME_2)) { if ( !sftk_hasAttribute(object, CKA_PRIME_2)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_mod_component++;
} }
if ( !sftk_hasAttribute(object, CKA_EXPONENT_1)) { if ( !sftk_hasAttribute(object, CKA_EXPONENT_1)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_crt_component++;
} }
if ( !sftk_hasAttribute(object, CKA_EXPONENT_2)) { if ( !sftk_hasAttribute(object, CKA_EXPONENT_2)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_crt_component++;
} }
if ( !sftk_hasAttribute(object, CKA_COEFFICIENT)) { if ( !sftk_hasAttribute(object, CKA_COEFFICIENT)) {
return CKR_TEMPLATE_INCOMPLETE; missing_rsa_crt_component++;
} }
if (missing_rsa_mod_component || missing_rsa_exp_component ||
missing_rsa_crt_component) {
/* we are missing a component, see if we have enough to rebuild
* the rest */
int have_exp = 2- missing_rsa_exp_component;
int have_component = 5-
(missing_rsa_exp_component+missing_rsa_mod_component);
SECStatus rv;
if ((have_exp == 0) || (have_component < 3)) {
/* nope, not enough to reconstruct the private key */
return CKR_TEMPLATE_INCOMPLETE;
}
/*fill in the missing parameters */
rv = sftk_fillRSAPrivateKey(object);
if (rv != SECSuccess) {
return CKR_TEMPLATE_INCOMPLETE;
}
}
/* make sure Netscape DB attribute is set correctly */ /* make sure Netscape DB attribute is set correctly */
crv = sftk_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS); crv = sftk_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS);
if (crv != CKR_OK) return crv; if (crv != CKR_OK) return crv;
@ -1057,6 +1103,20 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
wrap = CK_FALSE; wrap = CK_FALSE;
break; break;
#endif /* NSS_ENABLE_ECC */ #endif /* NSS_ENABLE_ECC */
case CKK_NSS_JPAKE_ROUND1:
if (!sftk_hasAttribute(object, CKA_PRIME ||
!sftk_hasAttribute(object, CKA_SUBPRIME) ||
!sftk_hasAttribute(object, CKA_BASE))) {
return CKR_TEMPLATE_INCOMPLETE;
}
/* fall through */
case CKK_NSS_JPAKE_ROUND2:
/* CKA_NSS_JPAKE_SIGNERID and CKA_NSS_JPAKE_PEERID are checked in
the J-PAKE code. */
encrypt = sign = recover = wrap = CK_FALSE;
derive = CK_TRUE;
createObjectInfo = PR_FALSE;
break;
default: default:
return CKR_ATTRIBUTE_VALUE_INVALID; return CKR_ATTRIBUTE_VALUE_INVALID;
} }
@ -1099,7 +1159,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
crv = sftkdb_write(keyHandle, object, &object->handle); crv = sftkdb_write(keyHandle, object, &object->handle);
sftk_freeDB(keyHandle); sftk_freeDB(keyHandle);
return crv; return crv;
} else { } else if (createObjectInfo) {
object->objectInfo = sftk_mkPrivKey(object,key_type,&crv); object->objectInfo = sftk_mkPrivKey(object,key_type,&crv);
if (object->objectInfo == NULL) return crv; if (object->objectInfo == NULL) return crv;
object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey; object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey;
@ -1835,6 +1895,116 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
return privKey; return privKey;
} }
/*
* we have a partial rsa private key, fill in the rest
*/
static SECStatus
sftk_fillRSAPrivateKey(SFTKObject *object)
{
RSAPrivateKey tmpKey = { 0 };
SFTKAttribute *modulus = NULL;
SFTKAttribute *prime1 = NULL;
SFTKAttribute *prime2 = NULL;
SFTKAttribute *privateExponent = NULL;
SFTKAttribute *publicExponent = NULL;
SECStatus rv;
CK_RV crv;
/* first fill in the components that we have. Populate only uses
* the non-crt components, so only fill those in */
tmpKey.arena = NULL;
modulus = sftk_FindAttribute(object, CKA_MODULUS);
if (modulus) {
tmpKey.modulus.data = modulus->attrib.pValue;
tmpKey.modulus.len = modulus->attrib.ulValueLen;
}
prime1 = sftk_FindAttribute(object, CKA_PRIME_1);
if (prime1) {
tmpKey.prime1.data = prime1->attrib.pValue;
tmpKey.prime1.len = prime1->attrib.ulValueLen;
}
prime2 = sftk_FindAttribute(object, CKA_PRIME_2);
if (prime2) {
tmpKey.prime2.data = prime2->attrib.pValue;
tmpKey.prime2.len = prime2->attrib.ulValueLen;
}
privateExponent = sftk_FindAttribute(object, CKA_PRIVATE_EXPONENT);
if (privateExponent) {
tmpKey.privateExponent.data = privateExponent->attrib.pValue;
tmpKey.privateExponent.len = privateExponent->attrib.ulValueLen;
}
publicExponent = sftk_FindAttribute(object, CKA_PUBLIC_EXPONENT);
if (publicExponent) {
tmpKey.publicExponent.data = publicExponent->attrib.pValue;
tmpKey.publicExponent.len = publicExponent->attrib.ulValueLen;
}
/*
* populate requires one exponent plus 2 other components to work.
* we expected our caller to check that first. If that didn't happen,
* populate will simply return an error here.
*/
rv = RSA_PopulatePrivateKey(&tmpKey);
if (rv != SECSuccess) {
goto loser;
}
/* now that we have a fully populated key, set all our attribute values */
rv = SECFailure;
crv = sftk_forceAttribute(object,CKA_MODULUS,
sftk_item_expand(&tmpKey.modulus));
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object,CKA_PUBLIC_EXPONENT,
sftk_item_expand(&tmpKey.publicExponent));
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object,CKA_PRIVATE_EXPONENT,
sftk_item_expand(&tmpKey.privateExponent));
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object,CKA_PRIME_1,
sftk_item_expand(&tmpKey.prime1));
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object,CKA_PRIME_2,
sftk_item_expand(&tmpKey.prime2));
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object,CKA_EXPONENT_1,
sftk_item_expand(&tmpKey.exponent1));
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object,CKA_EXPONENT_2,
sftk_item_expand(&tmpKey.exponent2));
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object,CKA_COEFFICIENT,
sftk_item_expand(&tmpKey.coefficient));
if (crv != CKR_OK) goto loser;
rv = SECSuccess;
/* we're done (one way or the other), clean up all our stuff */
loser:
if (tmpKey.arena) {
PORT_FreeArena(tmpKey.arena,PR_TRUE);
}
if (modulus) {
sftk_FreeAttribute(modulus);
}
if (prime1) {
sftk_FreeAttribute(prime1);
}
if (prime2) {
sftk_FreeAttribute(prime2);
}
if (privateExponent) {
sftk_FreeAttribute(privateExponent);
}
if (publicExponent) {
sftk_FreeAttribute(publicExponent);
}
return rv;
}
/* Generate a low private key structure from an object */ /* Generate a low private key structure from an object */
NSSLOWKEYPrivateKey * NSSLOWKEYPrivateKey *

Просмотреть файл

@ -3141,7 +3141,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
int i; int i;
SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
unsigned char buf[MAX_KEY_LEN]; unsigned char buf[MAX_KEY_LEN];
enum {nsc_pbe, nsc_ssl, nsc_bulk, nsc_param} key_gen_type; enum {nsc_pbe, nsc_ssl, nsc_bulk, nsc_param, nsc_jpake} key_gen_type;
NSSPKCS5PBEParameter *pbe_param; NSSPKCS5PBEParameter *pbe_param;
SSL3RSAPreMasterSecret *rsa_pms; SSL3RSAPreMasterSecret *rsa_pms;
CK_VERSION *version; CK_VERSION *version;
@ -3150,6 +3150,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
* produce them any more. The affected algorithm was 3DES. * produce them any more. The affected algorithm was 3DES.
*/ */
PRBool faultyPBE3DES = PR_FALSE; PRBool faultyPBE3DES = PR_FALSE;
HASH_HashType hashType;
CHECK_FORK(); CHECK_FORK();
@ -3249,6 +3250,24 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
objclass = CKO_KG_PARAMETERS; objclass = CKO_KG_PARAMETERS;
crv = CKR_OK; crv = CKR_OK;
break; break;
case CKM_NSS_JPAKE_ROUND1_SHA1: hashType = HASH_AlgSHA1; goto jpake1;
case CKM_NSS_JPAKE_ROUND1_SHA256: hashType = HASH_AlgSHA256; goto jpake1;
case CKM_NSS_JPAKE_ROUND1_SHA384: hashType = HASH_AlgSHA384; goto jpake1;
case CKM_NSS_JPAKE_ROUND1_SHA512: hashType = HASH_AlgSHA512; goto jpake1;
jpake1:
key_gen_type = nsc_jpake;
key_type = CKK_NSS_JPAKE_ROUND1;
objclass = CKO_PRIVATE_KEY;
if (pMechanism->pParameter == NULL ||
pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound1Params)) {
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
if (sftk_isTrue(key, CKA_TOKEN)) {
crv = CKR_TEMPLATE_INCONSISTENT;
}
crv = CKR_OK;
break;
default: default:
crv = CKR_MECHANISM_INVALID; crv = CKR_MECHANISM_INVALID;
break; break;
@ -3295,6 +3314,11 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
*buf = 0; *buf = 0;
crv = nsc_parameter_gen(key_type,key); crv = nsc_parameter_gen(key_type,key);
break; break;
case nsc_jpake:
crv = jpake_Round1(hashType,
(CK_NSS_JPAKERound1Params *) pMechanism->pParameter,
key);
break;
} }
if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
@ -5000,8 +5024,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession); SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession);
SFTKObject * key; SFTKObject * key;
SFTKObject * sourceKey; SFTKObject * sourceKey;
SFTKAttribute * att; SFTKAttribute * att = NULL;
SFTKAttribute * att2; SFTKAttribute * att2 = NULL;
unsigned char * buf; unsigned char * buf;
SHA1Context * sha; SHA1Context * sha;
MD5Context * md5; MD5Context * md5;
@ -5024,6 +5048,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
unsigned char key_block[NUM_MIXERS * MD5_LENGTH]; unsigned char key_block[NUM_MIXERS * MD5_LENGTH];
unsigned char key_block2[MD5_LENGTH]; unsigned char key_block2[MD5_LENGTH];
PRBool isFIPS; PRBool isFIPS;
HASH_HashType hashType;
PRBool extractValue = PR_TRUE;
CHECK_FORK(); CHECK_FORK();
@ -5061,8 +5087,24 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
keySize = sftk_MapKeySize(keyType); keySize = sftk_MapKeySize(keyType);
} }
/* Derive can only create SECRET KEY's currently... */ switch (pMechanism->mechanism) {
classType = CKO_SECRET_KEY; case CKM_NSS_JPAKE_ROUND2_SHA1: /* fall through */
case CKM_NSS_JPAKE_ROUND2_SHA256: /* fall through */
case CKM_NSS_JPAKE_ROUND2_SHA384: /* fall through */
case CKM_NSS_JPAKE_ROUND2_SHA512:
extractValue = PR_FALSE;
classType = CKO_PRIVATE_KEY;
break;
case CKM_NSS_JPAKE_FINAL_SHA1: /* fall through */
case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */
case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */
case CKM_NSS_JPAKE_FINAL_SHA512:
extractValue = PR_FALSE;
/* fall through */
default:
classType = CKO_SECRET_KEY;
}
crv = sftk_forceAttribute (key,CKA_CLASS,&classType,sizeof(classType)); crv = sftk_forceAttribute (key,CKA_CLASS,&classType,sizeof(classType));
if (crv != CKR_OK) { if (crv != CKR_OK) {
sftk_FreeObject(key); sftk_FreeObject(key);
@ -5083,12 +5125,14 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
return CKR_KEY_HANDLE_INVALID; return CKR_KEY_HANDLE_INVALID;
} }
/* get the value of the base key */ if (extractValue) {
att = sftk_FindAttribute(sourceKey,CKA_VALUE); /* get the value of the base key */
if (att == NULL) { att = sftk_FindAttribute(sourceKey,CKA_VALUE);
sftk_FreeObject(key); if (att == NULL) {
sftk_FreeObject(sourceKey); sftk_FreeObject(key);
return CKR_KEY_HANDLE_INVALID; sftk_FreeObject(sourceKey);
return CKR_KEY_HANDLE_INVALID;
}
} }
switch (pMechanism->mechanism) { switch (pMechanism->mechanism) {
@ -6008,10 +6052,161 @@ ec_loser:
} }
#endif /* NSS_ENABLE_ECC */ #endif /* NSS_ENABLE_ECC */
/* See RFC 5869 and CK_NSS_HKDFParams for documentation. */
case CKM_NSS_HKDF_SHA1: hashType = HASH_AlgSHA1; goto hkdf;
case CKM_NSS_HKDF_SHA256: hashType = HASH_AlgSHA256; goto hkdf;
case CKM_NSS_HKDF_SHA384: hashType = HASH_AlgSHA384; goto hkdf;
case CKM_NSS_HKDF_SHA512: hashType = HASH_AlgSHA512; goto hkdf;
hkdf: {
const CK_NSS_HKDFParams * params =
(const CK_NSS_HKDFParams *) pMechanism->pParameter;
const SECHashObject * rawHash;
unsigned hashLen;
CK_BYTE buf[HASH_LENGTH_MAX];
/* const */ CK_BYTE * prk; /* psuedo-random key */
CK_ULONG prkLen;
const CK_BYTE * okm; /* output keying material */
rawHash = HASH_GetRawHashObject(hashType);
if (rawHash == NULL || rawHash->length > sizeof buf) {
crv = CKR_FUNCTION_FAILED;
break;
}
hashLen = rawHash->length;
if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams) ||
!params || (!params->bExpand && !params->bExtract) ||
(params->bExtract && params->ulSaltLen > 0 && !params->pSalt) ||
(params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) {
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
if (keySize == 0 || keySize > sizeof key_block ||
(!params->bExpand && keySize > hashLen) ||
(params->bExpand && keySize > 255 * hashLen)) {
crv = CKR_TEMPLATE_INCONSISTENT;
break;
}
crv = sftk_DeriveSensitiveCheck(sourceKey, key);
if (crv != CKR_OK)
break;
/* HKDF-Extract(salt, base key value) */
if (params->bExtract) {
CK_BYTE * salt;
CK_ULONG saltLen;
HMACContext * hmac;
unsigned int bufLen;
salt = params->pSalt;
saltLen = params->ulSaltLen;
if (salt == NULL) {
saltLen = hashLen;
salt = buf;
memset(salt, 0, saltLen);
}
hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
if (!hmac) {
crv = CKR_HOST_MEMORY;
break;
}
HMAC_Begin(hmac);
HMAC_Update(hmac, (const unsigned char*) att->attrib.pValue,
att->attrib.ulValueLen);
HMAC_Finish(hmac, buf, &bufLen, sizeof(buf));
HMAC_Destroy(hmac, PR_TRUE);
PORT_Assert(bufLen == rawHash->length);
prk = buf;
prkLen = bufLen;
} else {
/* PRK = base key value */
prk = (CK_BYTE*) att->attrib.pValue;
prkLen = att->attrib.ulValueLen;
}
/* HKDF-Expand */
if (!params->bExpand) {
okm = prk;
} else {
/* T(1) = HMAC-Hash(prk, "" | info | 0x01)
* T(n) = HMAC-Hash(prk, T(n-1) | info | n
* key material = T(1) | ... | T(n)
*/
HMACContext * hmac;
CK_BYTE i;
unsigned iterations = PR_ROUNDUP(keySize, hashLen) / hashLen;
hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
if (hmac == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
for (i = 1; i <= iterations; ++i) {
unsigned len;
HMAC_Begin(hmac);
if (i > 1) {
HMAC_Update(hmac, key_block + ((i-2) * hashLen), hashLen);
}
if (params->ulInfoLen != 0) {
HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
}
HMAC_Update(hmac, &i, 1);
HMAC_Finish(hmac, key_block + ((i-1) * hashLen), &len,
hashLen);
PORT_Assert(len == hashLen);
}
HMAC_Destroy(hmac, PR_TRUE);
okm = key_block;
}
/* key material = prk */
crv = sftk_forceAttribute(key, CKA_VALUE, okm, keySize);
break;
} /* end of CKM_NSS_HKDF_* */
case CKM_NSS_JPAKE_ROUND2_SHA1: hashType = HASH_AlgSHA1; goto jpake2;
case CKM_NSS_JPAKE_ROUND2_SHA256: hashType = HASH_AlgSHA256; goto jpake2;
case CKM_NSS_JPAKE_ROUND2_SHA384: hashType = HASH_AlgSHA384; goto jpake2;
case CKM_NSS_JPAKE_ROUND2_SHA512: hashType = HASH_AlgSHA512; goto jpake2;
jpake2:
if (pMechanism->pParameter == NULL ||
pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params))
crv = CKR_MECHANISM_PARAM_INVALID;
if (crv == CKR_OK && sftk_isTrue(key, CKA_TOKEN))
crv = CKR_TEMPLATE_INCONSISTENT;
if (crv == CKR_OK)
crv = sftk_DeriveSensitiveCheck(sourceKey, key);
if (crv == CKR_OK)
crv = jpake_Round2(hashType,
(CK_NSS_JPAKERound2Params *) pMechanism->pParameter,
sourceKey, key);
break;
case CKM_NSS_JPAKE_FINAL_SHA1: hashType = HASH_AlgSHA1; goto jpakeFinal;
case CKM_NSS_JPAKE_FINAL_SHA256: hashType = HASH_AlgSHA256; goto jpakeFinal;
case CKM_NSS_JPAKE_FINAL_SHA384: hashType = HASH_AlgSHA384; goto jpakeFinal;
case CKM_NSS_JPAKE_FINAL_SHA512: hashType = HASH_AlgSHA512; goto jpakeFinal;
jpakeFinal:
if (pMechanism->pParameter == NULL ||
pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams))
crv = CKR_MECHANISM_PARAM_INVALID;
/* We purposely do not do the derive sensitivity check; we want to be
able to derive non-sensitive keys while allowing the ROUND1 and
ROUND2 keys to be sensitive (which they always are, since they are
in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE
in the template in order for the resultant keyblock key to be
sensitive.
*/
if (crv == CKR_OK)
crv = jpake_Final(hashType,
(CK_NSS_JPAKEFinalParams *) pMechanism->pParameter,
sourceKey, key);
break;
default: default:
crv = CKR_MECHANISM_INVALID; crv = CKR_MECHANISM_INVALID;
} }
sftk_FreeAttribute(att); if (att) {
sftk_FreeAttribute(att);
}
sftk_FreeObject(sourceKey); sftk_FreeObject(sourceKey);
if (crv != CKR_OK) { if (crv != CKR_OK) {
if (key) sftk_FreeObject(key); if (key) sftk_FreeObject(key);

Просмотреть файл

@ -46,7 +46,7 @@
#include "pkcs11t.h" #include "pkcs11t.h"
#include "sftkdbt.h" #include "sftkdbt.h"
#include "hasht.h"
/* /*
* Configuration Defines * Configuration Defines
@ -702,6 +702,21 @@ SFTKObject * sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey,
CK_OBJECT_HANDLE handle); CK_OBJECT_HANDLE handle);
SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so); SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so);
/* J-PAKE (jpakesftk.c) */
extern
CK_RV jpake_Round1(HASH_HashType hashType,
CK_NSS_JPAKERound1Params * params,
SFTKObject * key);
extern
CK_RV jpake_Round2(HASH_HashType hashType,
CK_NSS_JPAKERound2Params * params,
SFTKObject * sourceKey, SFTKObject * key);
extern
CK_RV jpake_Final(HASH_HashType hashType,
const CK_NSS_JPAKEFinalParams * params,
SFTKObject * sourceKey, SFTKObject * key);
/**************************************** /****************************************
* implement TLS Pseudo Random Function (PRF) * implement TLS Pseudo Random Function (PRF)
*/ */

Просмотреть файл

@ -57,11 +57,11 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/ */
#define SOFTOKEN_VERSION "3.12.8.0" SOFTOKEN_ECC_STRING #define SOFTOKEN_VERSION "3.12.9.0" SOFTOKEN_ECC_STRING " Beta"
#define SOFTOKEN_VMAJOR 3 #define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 12 #define SOFTOKEN_VMINOR 12
#define SOFTOKEN_VPATCH 8 #define SOFTOKEN_VPATCH 9
#define SOFTOKEN_VBUILD 0 #define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE #define SOFTOKEN_BETA PR_TRUE
#endif /* _SOFTKVER_H_ */ #endif /* _SOFTKVER_H_ */

Просмотреть файл

@ -51,11 +51,11 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/ */
#define NSSUTIL_VERSION "3.12.8.0" #define NSSUTIL_VERSION "3.12.9.0 Beta"
#define NSSUTIL_VMAJOR 3 #define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 12 #define NSSUTIL_VMINOR 12
#define NSSUTIL_VPATCH 8 #define NSSUTIL_VPATCH 9
#define NSSUTIL_VBUILD 0 #define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE #define NSSUTIL_BETA PR_TRUE
#endif /* __nssutil_h_ */ #endif /* __nssutil_h_ */

Просмотреть файл

@ -39,7 +39,7 @@
#define _PKCS11N_H_ #define _PKCS11N_H_
#ifdef DEBUG #ifdef DEBUG
static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.19 $ $Date: 2009/03/25 05:21:03 $"; static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.19.22.2 $ $Date: 2010/12/04 19:10:46 $";
#endif /* DEBUG */ #endif /* DEBUG */
/* /*
@ -84,6 +84,10 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.19 $
#define CKK_NSS (CKK_VENDOR_DEFINED|NSSCK_VENDOR_NSS) #define CKK_NSS (CKK_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
#define CKK_NSS_PKCS8 (CKK_NSS + 1) #define CKK_NSS_PKCS8 (CKK_NSS + 1)
#define CKK_NSS_JPAKE_ROUND1 (CKK_NSS + 2)
#define CKK_NSS_JPAKE_ROUND2 (CKK_NSS + 3)
/* /*
* NSS-defined certificate types * NSS-defined certificate types
* *
@ -116,6 +120,15 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.19 $
#define CKA_NSS_MODULE_SPEC (CKA_NSS + 24) #define CKA_NSS_MODULE_SPEC (CKA_NSS + 24)
#define CKA_NSS_OVERRIDE_EXTENSIONS (CKA_NSS + 25) #define CKA_NSS_OVERRIDE_EXTENSIONS (CKA_NSS + 25)
#define CKA_NSS_JPAKE_SIGNERID (CKA_NSS + 26)
#define CKA_NSS_JPAKE_PEERID (CKA_NSS + 27)
#define CKA_NSS_JPAKE_GX1 (CKA_NSS + 28)
#define CKA_NSS_JPAKE_GX2 (CKA_NSS + 29)
#define CKA_NSS_JPAKE_GX3 (CKA_NSS + 30)
#define CKA_NSS_JPAKE_GX4 (CKA_NSS + 31)
#define CKA_NSS_JPAKE_X2 (CKA_NSS + 32)
#define CKA_NSS_JPAKE_X2S (CKA_NSS + 33)
/* /*
* Trust attributes: * Trust attributes:
* *
@ -168,6 +181,54 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.19 $
#define CKM_NSS_AES_KEY_WRAP (CKM_NSS + 1) #define CKM_NSS_AES_KEY_WRAP (CKM_NSS + 1)
#define CKM_NSS_AES_KEY_WRAP_PAD (CKM_NSS + 2) #define CKM_NSS_AES_KEY_WRAP_PAD (CKM_NSS + 2)
/* HKDF key derivation mechanisms. See CK_NSS_HKDFParams for documentation. */
#define CKM_NSS_HKDF_SHA1 (CKM_NSS + 3)
#define CKM_NSS_HKDF_SHA256 (CKM_NSS + 4)
#define CKM_NSS_HKDF_SHA384 (CKM_NSS + 5)
#define CKM_NSS_HKDF_SHA512 (CKM_NSS + 6)
/* J-PAKE round 1 key generation mechanisms.
*
* Required template attributes: CKA_PRIME, CKA_SUBPRIME, CKA_BASE,
* CKA_NSS_JPAKE_SIGNERID
* Output key type: CKK_NSS_JPAKE_ROUND1
* Output key class: CKO_PRIVATE_KEY
* Parameter type: CK_NSS_JPAKERound1Params
*
*/
#define CKM_NSS_JPAKE_ROUND1_SHA1 (CKM_NSS + 7)
#define CKM_NSS_JPAKE_ROUND1_SHA256 (CKM_NSS + 8)
#define CKM_NSS_JPAKE_ROUND1_SHA384 (CKM_NSS + 9)
#define CKM_NSS_JPAKE_ROUND1_SHA512 (CKM_NSS + 10)
/* J-PAKE round 2 key derivation mechanisms.
*
* Required template attributes: CKA_NSS_JPAKE_PEERID
* Input key type: CKK_NSS_JPAKE_ROUND1
* Output key type: CKK_NSS_JPAKE_ROUND2
* Output key class: CKO_PRIVATE_KEY
* Parameter type: CK_NSS_JPAKERound2Params
*/
#define CKM_NSS_JPAKE_ROUND2_SHA1 (CKM_NSS + 11)
#define CKM_NSS_JPAKE_ROUND2_SHA256 (CKM_NSS + 12)
#define CKM_NSS_JPAKE_ROUND2_SHA384 (CKM_NSS + 13)
#define CKM_NSS_JPAKE_ROUND2_SHA512 (CKM_NSS + 14)
/* J-PAKE final key material derivation mechanisms
*
* Input key type: CKK_NSS_JPAKE_ROUND2
* Output key type: CKK_GENERIC_SECRET
* Output key class: CKO_SECRET_KEY
* Parameter type: CK_NSS_JPAKEFinalParams
*
* You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material
* to get a key with uniformly distributed bits.
*/
#define CKM_NSS_JPAKE_FINAL_SHA1 (CKM_NSS + 15)
#define CKM_NSS_JPAKE_FINAL_SHA256 (CKM_NSS + 16)
#define CKM_NSS_JPAKE_FINAL_SHA384 (CKM_NSS + 17)
#define CKM_NSS_JPAKE_FINAL_SHA512 (CKM_NSS + 18)
/* /*
* HISTORICAL: * HISTORICAL:
* Do not attempt to use these. They are only used by NETSCAPE's internal * Do not attempt to use these. They are only used by NETSCAPE's internal
@ -187,6 +248,32 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.19 $
#define CKM_TLS_PRF_GENERAL 0x80000373UL #define CKM_TLS_PRF_GENERAL 0x80000373UL
typedef struct CK_NSS_JPAKEPublicValue {
CK_BYTE * pGX;
CK_ULONG ulGXLen;
CK_BYTE * pGV;
CK_ULONG ulGVLen;
CK_BYTE * pR;
CK_ULONG ulRLen;
} CK_NSS_JPAKEPublicValue;
typedef struct CK_NSS_JPAKERound1Params {
CK_NSS_JPAKEPublicValue gx1; /* out */
CK_NSS_JPAKEPublicValue gx2; /* out */
} CK_NSS_JPAKERound1Params;
typedef struct CK_NSS_JPAKERound2Params {
CK_BYTE * pSharedKey; /* in */
CK_ULONG ulSharedKeyLen; /* in */
CK_NSS_JPAKEPublicValue gx3; /* in */
CK_NSS_JPAKEPublicValue gx4; /* in */
CK_NSS_JPAKEPublicValue A; /* out */
} CK_NSS_JPAKERound2Params;
typedef struct CK_NSS_JPAKEFinalParams {
CK_NSS_JPAKEPublicValue B; /* in */
} CK_NSS_JPAKEFinalParams;
/* /*
* NSS-defined return values * NSS-defined return values
* *
@ -196,6 +283,33 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.19 $
#define CKR_NSS_CERTDB_FAILED (CKR_NSS + 1) #define CKR_NSS_CERTDB_FAILED (CKR_NSS + 1)
#define CKR_NSS_KEYDB_FAILED (CKR_NSS + 2) #define CKR_NSS_KEYDB_FAILED (CKR_NSS + 2)
/* Mandatory parameter for the CKM_NSS_HKDF_* key deriviation mechanisms.
See RFC 5869.
bExtract: If set, HKDF-Extract will be applied to the input key. If
the optional salt is given, it is used; otherwise, the salt is
set to a sequence of zeros equal in length to the HMAC output.
If bExpand is not set, then the key template given to
C_DeriveKey must indicate an output key size less than or equal
to the output size of the HMAC.
bExpand: If set, HKDF-Expand will be applied to the input key (if
bExtract is not set) or to the result of HKDF-Extract (if
bExtract is set). Any info given in the optional pInfo field will
be included in the calculation.
The size of the output key must be specified in the template passed to
C_DeriveKey.
*/
typedef struct CK_NSS_HKDFParams {
CK_BBOOL bExtract;
CK_BYTE_PTR pSalt;
CK_ULONG ulSaltLen;
CK_BBOOL bExpand;
CK_BYTE_PTR pInfo;
CK_ULONG ulInfoLen;
} CK_NSS_HKDFParams;
/* /*
* Trust info * Trust info
* *

Просмотреть файл

@ -213,6 +213,7 @@ SEC_ERROR_OCSP_BAD_SIGNATURE = (SEC_ERROR_BASE + 157),
SEC_ERROR_OUT_OF_SEARCH_LIMITS = (SEC_ERROR_BASE + 158), SEC_ERROR_OUT_OF_SEARCH_LIMITS = (SEC_ERROR_BASE + 158),
SEC_ERROR_INVALID_POLICY_MAPPING = (SEC_ERROR_BASE + 159), SEC_ERROR_INVALID_POLICY_MAPPING = (SEC_ERROR_BASE + 159),
SEC_ERROR_POLICY_VALIDATION_FAILED = (SEC_ERROR_BASE + 160), SEC_ERROR_POLICY_VALIDATION_FAILED = (SEC_ERROR_BASE + 160),
/* No longer used. Unknown AIA location types are now silently ignored. */
SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE = (SEC_ERROR_BASE + 161), SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE = (SEC_ERROR_BASE + 161),
SEC_ERROR_BAD_HTTP_RESPONSE = (SEC_ERROR_BASE + 162), SEC_ERROR_BAD_HTTP_RESPONSE = (SEC_ERROR_BASE + 162),
SEC_ERROR_BAD_LDAP_RESPONSE = (SEC_ERROR_BASE + 163), SEC_ERROR_BAD_LDAP_RESPONSE = (SEC_ERROR_BASE + 163),
@ -231,6 +232,10 @@ SEC_ERROR_CRL_IMPORT_FAILED = (SEC_ERROR_BASE + 171),
SEC_ERROR_EXPIRED_PASSWORD = (SEC_ERROR_BASE + 172), SEC_ERROR_EXPIRED_PASSWORD = (SEC_ERROR_BASE + 172),
SEC_ERROR_LOCKED_PASSWORD = (SEC_ERROR_BASE + 173), SEC_ERROR_LOCKED_PASSWORD = (SEC_ERROR_BASE + 173),
SEC_ERROR_UNKNOWN_PKCS11_ERROR = (SEC_ERROR_BASE + 174),
SEC_ERROR_BAD_CRL_DP_URL = (SEC_ERROR_BASE + 175),
/* Add new error codes above here. */ /* Add new error codes above here. */
SEC_ERROR_END_OF_LIST SEC_ERROR_END_OF_LIST
} SECErrorCodes; } SECErrorCodes;