зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1550889 - land NSS 8082be3a6363 UPGRADE_NSS_RELEASE, r=me
--HG-- extra : rebase_source : 84cb27998d0b4e36d9a7d388e3a8b2a4fc3bb886
This commit is contained in:
Родитель
d88f3e04a9
Коммит
2f955dea5e
|
@ -1 +1 @@
|
|||
29a48b604602
|
||||
8082be3a6363
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
1 Added function:
|
||||
|
||||
'function SECStatus PK11_FindRawCertsWithSubject(PK11SlotInfo*, SECItem*, CERTCertificateList**)' {PK11_FindRawCertsWithSubject@@NSS_3.45}
|
|
@ -10,3 +10,4 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "pk11pqg.h"
|
||||
#include "pk11pub.h"
|
||||
#include "pkcs11uri.h"
|
||||
#include "secmod.h"
|
||||
|
||||
struct ScopedDelete {
|
||||
void operator()(CERTCertificate* cert) { CERT_DestroyCertificate(cert); }
|
||||
|
@ -47,6 +48,7 @@ struct ScopedDelete {
|
|||
SEC_PKCS12DecoderFinish(dcx);
|
||||
}
|
||||
void operator()(CERTDistNames* names) { CERT_FreeDistNames(names); }
|
||||
void operator()(SECMODModule* module) { SECMOD_DestroyModule(module); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -82,6 +84,7 @@ SCOPED(PK11Context);
|
|||
SCOPED(PK11GenericObject);
|
||||
SCOPED(SEC_PKCS12DecoderContext);
|
||||
SCOPED(CERTDistNames);
|
||||
SCOPED(SECMODModule);
|
||||
|
||||
#undef SCOPED
|
||||
|
||||
|
|
|
@ -8,7 +8,21 @@
|
|||
#define util_h__
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <codecvt>
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "nspr.h"
|
||||
|
||||
static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) {
|
||||
std::vector<uint8_t> bytes;
|
||||
|
@ -18,4 +32,81 @@ static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) {
|
|||
return bytes;
|
||||
}
|
||||
|
||||
// Given a prefix, attempts to create a unique directory that the user can do
|
||||
// work in without impacting other tests. For example, if given the prefix
|
||||
// "scratch", a directory like "scratch05c17b25" will be created in the current
|
||||
// working directory (or the location specified by NSS_GTEST_WORKDIR, if
|
||||
// defined).
|
||||
// Upon destruction, the implementation will attempt to delete the directory.
|
||||
// However, no attempt is made to first remove files in the directory - the
|
||||
// user is responsible for this. If the directory is not empty, deleting it will
|
||||
// fail.
|
||||
// Statistically, it is technically possible to fail to create a unique
|
||||
// directory name, but this is extremely unlikely given the expected workload of
|
||||
// this implementation.
|
||||
class ScopedUniqueDirectory {
|
||||
public:
|
||||
explicit ScopedUniqueDirectory(const std::string &prefix) {
|
||||
std::string path;
|
||||
const char *workingDirectory = PR_GetEnvSecure("NSS_GTEST_WORKDIR");
|
||||
if (workingDirectory) {
|
||||
path.assign(workingDirectory);
|
||||
}
|
||||
path.append(prefix);
|
||||
for (int i = 0; i < RETRY_LIMIT; i++) {
|
||||
std::string pathCopy(path);
|
||||
// TryMakingDirectory will modify its input. If it fails, we want to throw
|
||||
// away the modified result.
|
||||
if (TryMakingDirectory(pathCopy)) {
|
||||
mPath.assign(pathCopy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(mPath.length() > 0);
|
||||
#if defined(_WIN32)
|
||||
// sqldb always uses UTF-8 regardless of the current system locale.
|
||||
DWORD len =
|
||||
MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), nullptr, 0);
|
||||
std::vector<wchar_t> buf(len, L'\0');
|
||||
MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), buf.data(),
|
||||
buf.size());
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
mUTF8Path = converter.to_bytes(std::wstring(buf.begin(), buf.end()));
|
||||
#else
|
||||
mUTF8Path = mPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
// NB: the directory must be empty upon destruction
|
||||
~ScopedUniqueDirectory() { assert(rmdir(mPath.c_str()) == 0); }
|
||||
|
||||
const std::string &GetPath() { return mPath; }
|
||||
const std::string &GetUTF8Path() { return mUTF8Path; }
|
||||
|
||||
private:
|
||||
static const int RETRY_LIMIT = 5;
|
||||
|
||||
static void GenerateRandomName(/*in/out*/ std::string &prefix) {
|
||||
std::stringstream ss;
|
||||
ss << prefix;
|
||||
// RAND_MAX is at least 32767.
|
||||
ss << std::setfill('0') << std::setw(4) << std::hex << rand() << rand();
|
||||
// This will overwrite the value of prefix. This is a little inefficient,
|
||||
// but at least it makes the code simple.
|
||||
ss >> prefix;
|
||||
}
|
||||
|
||||
static bool TryMakingDirectory(/*in/out*/ std::string &prefix) {
|
||||
GenerateRandomName(prefix);
|
||||
#if defined(_WIN32)
|
||||
return _mkdir(prefix.c_str()) == 0;
|
||||
#else
|
||||
return mkdir(prefix.c_str(), 0777) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string mPath;
|
||||
std::string mUTF8Path;
|
||||
};
|
||||
|
||||
#endif // util_h__
|
||||
|
|
|
@ -7,6 +7,7 @@ DEPTH = ../..
|
|||
MODULE = nss
|
||||
|
||||
CPPSRCS = \
|
||||
pk11_aes_gcm_unittest.cc \
|
||||
pk11_aeskeywrap_unittest.cc \
|
||||
pk11_cbc_unittest.cc \
|
||||
pk11_chacha20poly1305_unittest.cc \
|
||||
|
@ -14,6 +15,7 @@ CPPSRCS = \
|
|||
pk11_ecdsa_unittest.cc \
|
||||
pk11_encrypt_derive_unittest.cc \
|
||||
pk11_export_unittest.cc \
|
||||
pk11_find_certs_unittest.cc \
|
||||
pk11_import_unittest.cc \
|
||||
pk11_pbkdf2_unittest.cc \
|
||||
pk11_prf_unittest.cc \
|
||||
|
|
|
@ -0,0 +1,347 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=4 et sw=4 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "nss.h"
|
||||
#include "pk11pub.h"
|
||||
#include "prenv.h"
|
||||
#include "prerror.h"
|
||||
#include "secmod.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
// These test certificates were generated using pycert/pykey from
|
||||
// mozilla-central (https://hg.mozilla.org/mozilla-central/file/ ...
|
||||
// 9968319230a74eb8c1953444a0e6973c7500a9f8/security/manager/ssl/ ...
|
||||
// tests/unit/pycert.py).
|
||||
|
||||
// issuer:test cert
|
||||
// subject:test cert
|
||||
// issuerKey:secp256r1
|
||||
// subjectKey:secp256r1
|
||||
// serialNumber:1
|
||||
std::vector<uint8_t> kTestCert1DER = {
|
||||
0x30, 0x82, 0x01, 0x1D, 0x30, 0x81, 0xC2, 0xA0, 0x03, 0x02, 0x01, 0x02,
|
||||
0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
|
||||
0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x09, 0x74, 0x65, 0x73, 0x74, 0x20,
|
||||
0x63, 0x65, 0x72, 0x74, 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x37,
|
||||
0x31, 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x18,
|
||||
0x0F, 0x32, 0x30, 0x32, 0x30, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x5A, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
|
||||
0x55, 0x04, 0x03, 0x0C, 0x09, 0x74, 0x65, 0x73, 0x74, 0x20, 0x63, 0x65,
|
||||
0x72, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE,
|
||||
0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01,
|
||||
0x07, 0x03, 0x42, 0x00, 0x04, 0x4F, 0xBF, 0xBB, 0xBB, 0x61, 0xE0, 0xF8,
|
||||
0xF9, 0xB1, 0xA6, 0x0A, 0x59, 0xAC, 0x87, 0x04, 0xE2, 0xEC, 0x05, 0x0B,
|
||||
0x42, 0x3E, 0x3C, 0xF7, 0x2E, 0x92, 0x3F, 0x2C, 0x4F, 0x79, 0x4B, 0x45,
|
||||
0x5C, 0x2A, 0x69, 0xD2, 0x33, 0x45, 0x6C, 0x36, 0xC4, 0x11, 0x9D, 0x07,
|
||||
0x06, 0xE0, 0x0E, 0xED, 0xC8, 0xD1, 0x93, 0x90, 0xD7, 0x99, 0x1B, 0x7B,
|
||||
0x2D, 0x07, 0xA3, 0x04, 0xEA, 0xA0, 0x4A, 0xA6, 0xC0, 0x30, 0x0D, 0x06,
|
||||
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00,
|
||||
0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x5C, 0x75, 0x51, 0x9F, 0x13,
|
||||
0x11, 0x50, 0xCD, 0x5D, 0x8A, 0xDE, 0x20, 0xA3, 0xBC, 0x06, 0x30, 0x91,
|
||||
0xFF, 0xB2, 0x73, 0x75, 0x5F, 0x31, 0x64, 0xEC, 0xFD, 0xCB, 0x42, 0x80,
|
||||
0x0A, 0x70, 0xE6, 0x02, 0x20, 0x11, 0xFA, 0xA2, 0xCA, 0x06, 0xF3, 0xBC,
|
||||
0x5F, 0x8A, 0xCA, 0x17, 0x63, 0x36, 0x87, 0xCF, 0x8D, 0x5C, 0xA0, 0x56,
|
||||
0x84, 0x44, 0x61, 0xB2, 0x33, 0x42, 0x07, 0x58, 0x9F, 0x0C, 0x9E, 0x49,
|
||||
0x83,
|
||||
};
|
||||
|
||||
// issuer:test cert
|
||||
// subject:test cert
|
||||
// issuerKey:secp256r1
|
||||
// subjectKey:secp256r1
|
||||
// serialNumber:2
|
||||
std::vector<uint8_t> kTestCert2DER = {
|
||||
0x30, 0x82, 0x01, 0x1E, 0x30, 0x81, 0xC2, 0xA0, 0x03, 0x02, 0x01, 0x02,
|
||||
0x02, 0x01, 0x02, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
|
||||
0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x09, 0x74, 0x65, 0x73, 0x74, 0x20,
|
||||
0x63, 0x65, 0x72, 0x74, 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x37,
|
||||
0x31, 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x18,
|
||||
0x0F, 0x32, 0x30, 0x32, 0x30, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x5A, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
|
||||
0x55, 0x04, 0x03, 0x0C, 0x09, 0x74, 0x65, 0x73, 0x74, 0x20, 0x63, 0x65,
|
||||
0x72, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE,
|
||||
0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01,
|
||||
0x07, 0x03, 0x42, 0x00, 0x04, 0x4F, 0xBF, 0xBB, 0xBB, 0x61, 0xE0, 0xF8,
|
||||
0xF9, 0xB1, 0xA6, 0x0A, 0x59, 0xAC, 0x87, 0x04, 0xE2, 0xEC, 0x05, 0x0B,
|
||||
0x42, 0x3E, 0x3C, 0xF7, 0x2E, 0x92, 0x3F, 0x2C, 0x4F, 0x79, 0x4B, 0x45,
|
||||
0x5C, 0x2A, 0x69, 0xD2, 0x33, 0x45, 0x6C, 0x36, 0xC4, 0x11, 0x9D, 0x07,
|
||||
0x06, 0xE0, 0x0E, 0xED, 0xC8, 0xD1, 0x93, 0x90, 0xD7, 0x99, 0x1B, 0x7B,
|
||||
0x2D, 0x07, 0xA3, 0x04, 0xEA, 0xA0, 0x4A, 0xA6, 0xC0, 0x30, 0x0D, 0x06,
|
||||
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00,
|
||||
0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x5C, 0x75, 0x51, 0x9F, 0x13,
|
||||
0x11, 0x50, 0xCD, 0x5D, 0x8A, 0xDE, 0x20, 0xA3, 0xBC, 0x06, 0x30, 0x91,
|
||||
0xFF, 0xB2, 0x73, 0x75, 0x5F, 0x31, 0x64, 0xEC, 0xFD, 0xCB, 0x42, 0x80,
|
||||
0x0A, 0x70, 0xE6, 0x02, 0x21, 0x00, 0xF6, 0x5E, 0x42, 0xC7, 0x54, 0x40,
|
||||
0x81, 0xE9, 0x4C, 0x16, 0x48, 0xB1, 0x39, 0x0A, 0xA0, 0xE2, 0x8C, 0x23,
|
||||
0xAA, 0xC5, 0xBB, 0xAC, 0xEB, 0x9B, 0x15, 0x0B, 0x2F, 0xB7, 0xF5, 0x85,
|
||||
0xB2, 0x54,
|
||||
};
|
||||
|
||||
std::vector<uint8_t> kTestCertSubjectDER = {
|
||||
0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
|
||||
0x0C, 0x09, 0x74, 0x65, 0x73, 0x74, 0x20, 0x63, 0x65, 0x72, 0x74,
|
||||
};
|
||||
|
||||
// issuer:test cert
|
||||
// subject:unrelated subject DN
|
||||
// issuerKey:secp256r1
|
||||
// subjectKey:secp256r1
|
||||
// serialNumber:3
|
||||
std::vector<uint8_t> kUnrelatedTestCertDER = {
|
||||
0x30, 0x82, 0x01, 0x28, 0x30, 0x81, 0xCD, 0xA0, 0x03, 0x02, 0x01, 0x02,
|
||||
0x02, 0x01, 0x03, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
|
||||
0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x09, 0x74, 0x65, 0x73, 0x74, 0x20,
|
||||
0x63, 0x65, 0x72, 0x74, 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x37,
|
||||
0x31, 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x18,
|
||||
0x0F, 0x32, 0x30, 0x32, 0x30, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x5A, 0x30, 0x1F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03,
|
||||
0x55, 0x04, 0x03, 0x0C, 0x14, 0x75, 0x6E, 0x72, 0x65, 0x6C, 0x61, 0x74,
|
||||
0x65, 0x64, 0x20, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x44,
|
||||
0x4E, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
|
||||
0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07,
|
||||
0x03, 0x42, 0x00, 0x04, 0x4F, 0xBF, 0xBB, 0xBB, 0x61, 0xE0, 0xF8, 0xF9,
|
||||
0xB1, 0xA6, 0x0A, 0x59, 0xAC, 0x87, 0x04, 0xE2, 0xEC, 0x05, 0x0B, 0x42,
|
||||
0x3E, 0x3C, 0xF7, 0x2E, 0x92, 0x3F, 0x2C, 0x4F, 0x79, 0x4B, 0x45, 0x5C,
|
||||
0x2A, 0x69, 0xD2, 0x33, 0x45, 0x6C, 0x36, 0xC4, 0x11, 0x9D, 0x07, 0x06,
|
||||
0xE0, 0x0E, 0xED, 0xC8, 0xD1, 0x93, 0x90, 0xD7, 0x99, 0x1B, 0x7B, 0x2D,
|
||||
0x07, 0xA3, 0x04, 0xEA, 0xA0, 0x4A, 0xA6, 0xC0, 0x30, 0x0D, 0x06, 0x09,
|
||||
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03,
|
||||
0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x5C, 0x75, 0x51, 0x9F, 0x13, 0x11,
|
||||
0x50, 0xCD, 0x5D, 0x8A, 0xDE, 0x20, 0xA3, 0xBC, 0x06, 0x30, 0x91, 0xFF,
|
||||
0xB2, 0x73, 0x75, 0x5F, 0x31, 0x64, 0xEC, 0xFD, 0xCB, 0x42, 0x80, 0x0A,
|
||||
0x70, 0xE6, 0x02, 0x20, 0x0F, 0x1A, 0x04, 0xC2, 0xF8, 0xBA, 0xC2, 0x94,
|
||||
0x26, 0x6E, 0xBC, 0x91, 0x7D, 0xDB, 0x75, 0x7B, 0xE8, 0xA3, 0x4F, 0x69,
|
||||
0x1B, 0xF3, 0x1F, 0x2C, 0xCE, 0x82, 0x67, 0xC9, 0x5B, 0xBB, 0xBA, 0x0A,
|
||||
};
|
||||
|
||||
class PK11FindRawCertsBySubjectTest : public ::testing::Test {
|
||||
protected:
|
||||
PK11FindRawCertsBySubjectTest()
|
||||
: mSlot(nullptr), mTestCertDBDir("PK11FindRawCertsBySubjectTest-") {}
|
||||
|
||||
virtual void SetUp() {
|
||||
std::string testCertDBPath(mTestCertDBDir.GetPath());
|
||||
const char* testName =
|
||||
::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||
std::string modspec = "configDir='sql:";
|
||||
modspec.append(testCertDBPath);
|
||||
modspec.append("' tokenDescription='");
|
||||
modspec.append(testName);
|
||||
modspec.append("'");
|
||||
mSlot = SECMOD_OpenUserDB(modspec.c_str());
|
||||
ASSERT_NE(mSlot, nullptr);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
ASSERT_EQ(SECMOD_CloseUserDB(mSlot), SECSuccess);
|
||||
PK11_FreeSlot(mSlot);
|
||||
std::string testCertDBPath(mTestCertDBDir.GetPath());
|
||||
ASSERT_EQ(0, unlink((testCertDBPath + "/cert9.db").c_str()));
|
||||
ASSERT_EQ(0, unlink((testCertDBPath + "/key4.db").c_str()));
|
||||
}
|
||||
|
||||
PK11SlotInfo* mSlot;
|
||||
ScopedUniqueDirectory mTestCertDBDir;
|
||||
};
|
||||
|
||||
// If we don't have any certificates, we shouldn't get any when we search for
|
||||
// them.
|
||||
TEST_F(PK11FindRawCertsBySubjectTest, TestNoCertsImportedNoCertsFound) {
|
||||
SECItem subjectItem = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCertSubjectDER.data()),
|
||||
(unsigned int)kTestCertSubjectDER.size()};
|
||||
CERTCertificateList* certificates = nullptr;
|
||||
SECStatus rv =
|
||||
PK11_FindRawCertsWithSubject(mSlot, &subjectItem, &certificates);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
EXPECT_EQ(certificates, nullptr);
|
||||
}
|
||||
|
||||
// If we have one certificate but it has an unrelated subject DN, we shouldn't
|
||||
// get it when we search.
|
||||
TEST_F(PK11FindRawCertsBySubjectTest, TestOneCertImportedNoCertsFound) {
|
||||
char certNickname[] = "Unrelated Cert";
|
||||
SECItem certItem = {siBuffer,
|
||||
const_cast<unsigned char*>(kUnrelatedTestCertDER.data()),
|
||||
(unsigned int)kUnrelatedTestCertDER.size()};
|
||||
ASSERT_EQ(PK11_ImportDERCert(mSlot, &certItem, CK_INVALID_HANDLE,
|
||||
certNickname, false),
|
||||
SECSuccess);
|
||||
|
||||
SECItem subjectItem = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCertSubjectDER.data()),
|
||||
(unsigned int)kTestCertSubjectDER.size()};
|
||||
CERTCertificateList* certificates = nullptr;
|
||||
SECStatus rv =
|
||||
PK11_FindRawCertsWithSubject(mSlot, &subjectItem, &certificates);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
EXPECT_EQ(certificates, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(PK11FindRawCertsBySubjectTest, TestMultipleMatchingCertsFound) {
|
||||
char cert1Nickname[] = "Test Cert 1";
|
||||
SECItem cert1Item = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCert1DER.data()),
|
||||
(unsigned int)kTestCert1DER.size()};
|
||||
ASSERT_EQ(PK11_ImportDERCert(mSlot, &cert1Item, CK_INVALID_HANDLE,
|
||||
cert1Nickname, false),
|
||||
SECSuccess);
|
||||
char cert2Nickname[] = "Test Cert 2";
|
||||
SECItem cert2Item = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCert2DER.data()),
|
||||
(unsigned int)kTestCert2DER.size()};
|
||||
ASSERT_EQ(PK11_ImportDERCert(mSlot, &cert2Item, CK_INVALID_HANDLE,
|
||||
cert2Nickname, false),
|
||||
SECSuccess);
|
||||
char unrelatedCertNickname[] = "Unrelated Test Cert";
|
||||
SECItem unrelatedCertItem = {
|
||||
siBuffer, const_cast<unsigned char*>(kUnrelatedTestCertDER.data()),
|
||||
(unsigned int)kUnrelatedTestCertDER.size()};
|
||||
ASSERT_EQ(PK11_ImportDERCert(mSlot, &unrelatedCertItem, CK_INVALID_HANDLE,
|
||||
unrelatedCertNickname, false),
|
||||
SECSuccess);
|
||||
|
||||
CERTCertificateList* certificates = nullptr;
|
||||
SECItem subjectItem = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCertSubjectDER.data()),
|
||||
(unsigned int)kTestCertSubjectDER.size()};
|
||||
SECStatus rv =
|
||||
PK11_FindRawCertsWithSubject(mSlot, &subjectItem, &certificates);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
ASSERT_NE(certificates, nullptr);
|
||||
ScopedCERTCertificateList scopedCertificates(certificates);
|
||||
ASSERT_EQ(scopedCertificates->len, 2);
|
||||
|
||||
std::vector<uint8_t> foundCert1(
|
||||
scopedCertificates->certs[0].data,
|
||||
scopedCertificates->certs[0].data + scopedCertificates->certs[0].len);
|
||||
std::vector<uint8_t> foundCert2(
|
||||
scopedCertificates->certs[1].data,
|
||||
scopedCertificates->certs[1].data + scopedCertificates->certs[1].len);
|
||||
EXPECT_TRUE(foundCert1 == kTestCert1DER || foundCert1 == kTestCert2DER);
|
||||
EXPECT_TRUE(foundCert2 == kTestCert1DER || foundCert2 == kTestCert2DER);
|
||||
EXPECT_TRUE(foundCert1 != foundCert2);
|
||||
}
|
||||
|
||||
// If we try to search the internal slots, we won't find the certificate we just
|
||||
// imported (because it's on a different slot).
|
||||
TEST_F(PK11FindRawCertsBySubjectTest, TestNoCertsOnInternalSlots) {
|
||||
char cert1Nickname[] = "Test Cert 1";
|
||||
SECItem cert1Item = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCert1DER.data()),
|
||||
(unsigned int)kTestCert1DER.size()};
|
||||
ASSERT_EQ(PK11_ImportDERCert(mSlot, &cert1Item, CK_INVALID_HANDLE,
|
||||
cert1Nickname, false),
|
||||
SECSuccess);
|
||||
|
||||
SECItem subjectItem = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCertSubjectDER.data()),
|
||||
(unsigned int)kTestCertSubjectDER.size()};
|
||||
CERTCertificateList* internalKeySlotCertificates = nullptr;
|
||||
ScopedPK11SlotInfo internalKeySlot(PK11_GetInternalKeySlot());
|
||||
SECStatus rv = PK11_FindRawCertsWithSubject(
|
||||
internalKeySlot.get(), &subjectItem, &internalKeySlotCertificates);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
EXPECT_EQ(internalKeySlotCertificates, nullptr);
|
||||
|
||||
CERTCertificateList* internalSlotCertificates = nullptr;
|
||||
ScopedPK11SlotInfo internalSlot(PK11_GetInternalSlot());
|
||||
rv = PK11_FindRawCertsWithSubject(internalSlot.get(), &subjectItem,
|
||||
&internalSlotCertificates);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
EXPECT_EQ(internalSlotCertificates, nullptr);
|
||||
}
|
||||
|
||||
// issuer:test cert
|
||||
// subject:(empty - this had to be done by hand as pycert doesn't support this)
|
||||
// issuerKey:secp256r1
|
||||
// subjectKey:secp256r1
|
||||
// serialNumber:4
|
||||
std::vector<uint8_t> kEmptySubjectCertDER = {
|
||||
0x30, 0x82, 0x01, 0x09, 0x30, 0x81, 0xAE, 0xA0, 0x03, 0x02, 0x01, 0x02,
|
||||
0x02, 0x01, 0x04, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
|
||||
0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x09, 0x74, 0x65, 0x73, 0x74, 0x20,
|
||||
0x63, 0x65, 0x72, 0x74, 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x37,
|
||||
0x31, 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x18,
|
||||
0x0F, 0x32, 0x30, 0x32, 0x30, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x5A, 0x30, 0x00, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
|
||||
0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48,
|
||||
0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4F, 0xBF, 0xBB,
|
||||
0xBB, 0x61, 0xE0, 0xF8, 0xF9, 0xB1, 0xA6, 0x0A, 0x59, 0xAC, 0x87, 0x04,
|
||||
0xE2, 0xEC, 0x05, 0x0B, 0x42, 0x3E, 0x3C, 0xF7, 0x2E, 0x92, 0x3F, 0x2C,
|
||||
0x4F, 0x79, 0x4B, 0x45, 0x5C, 0x2A, 0x69, 0xD2, 0x33, 0x45, 0x6C, 0x36,
|
||||
0xC4, 0x11, 0x9D, 0x07, 0x06, 0xE0, 0x0E, 0xED, 0xC8, 0xD1, 0x93, 0x90,
|
||||
0xD7, 0x99, 0x1B, 0x7B, 0x2D, 0x07, 0xA3, 0x04, 0xEA, 0xA0, 0x4A, 0xA6,
|
||||
0xC0, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||
0x01, 0x0B, 0x05, 0x00, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x5C,
|
||||
0x75, 0x51, 0x9F, 0x13, 0x11, 0x50, 0xCD, 0x5D, 0x8A, 0xDE, 0x20, 0xA3,
|
||||
0xBC, 0x06, 0x30, 0x91, 0xFF, 0xB2, 0x73, 0x75, 0x5F, 0x31, 0x64, 0xEC,
|
||||
0xFD, 0xCB, 0x42, 0x80, 0x0A, 0x70, 0xE6, 0x02, 0x20, 0x31, 0x1B, 0x92,
|
||||
0xAA, 0xA8, 0xB7, 0x51, 0x52, 0x7B, 0x64, 0xD6, 0xF7, 0x2F, 0x0C, 0xFB,
|
||||
0xBB, 0xD5, 0xDF, 0x86, 0xA3, 0x97, 0x96, 0x60, 0x42, 0xDA, 0xD4, 0xA8,
|
||||
0x5F, 0x2F, 0xA4, 0xDE, 0x7C};
|
||||
|
||||
std::vector<uint8_t> kEmptySubjectDER = {0x30, 0x00};
|
||||
|
||||
// This certificate has the smallest possible subject. Finding it should work.
|
||||
TEST_F(PK11FindRawCertsBySubjectTest, TestFindEmptySubject) {
|
||||
char emptySubjectCertNickname[] = "Empty Subject Cert";
|
||||
SECItem emptySubjectCertItem = {
|
||||
siBuffer, const_cast<unsigned char*>(kEmptySubjectCertDER.data()),
|
||||
(unsigned int)kEmptySubjectCertDER.size()};
|
||||
ASSERT_EQ(PK11_ImportDERCert(mSlot, &emptySubjectCertItem, CK_INVALID_HANDLE,
|
||||
emptySubjectCertNickname, false),
|
||||
SECSuccess);
|
||||
|
||||
SECItem subjectItem = {siBuffer,
|
||||
const_cast<unsigned char*>(kEmptySubjectDER.data()),
|
||||
(unsigned int)kEmptySubjectDER.size()};
|
||||
CERTCertificateList* certificates = nullptr;
|
||||
SECStatus rv =
|
||||
PK11_FindRawCertsWithSubject(mSlot, &subjectItem, &certificates);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
ASSERT_NE(certificates, nullptr);
|
||||
ScopedCERTCertificateList scopedCertificates(certificates);
|
||||
ASSERT_EQ(scopedCertificates->len, 1);
|
||||
|
||||
std::vector<uint8_t> foundCert(
|
||||
scopedCertificates->certs[0].data,
|
||||
scopedCertificates->certs[0].data + scopedCertificates->certs[0].len);
|
||||
EXPECT_EQ(foundCert, kEmptySubjectCertDER);
|
||||
}
|
||||
|
||||
// Searching for a zero-length subject doesn't make sense (the minimum subject
|
||||
// is the SEQUENCE tag followed by a length byte of 0), but it shouldn't cause
|
||||
// problems.
|
||||
TEST_F(PK11FindRawCertsBySubjectTest, TestSearchForNullSubject) {
|
||||
char cert1Nickname[] = "Test Cert 1";
|
||||
SECItem cert1Item = {siBuffer,
|
||||
const_cast<unsigned char*>(kTestCert1DER.data()),
|
||||
(unsigned int)kTestCert1DER.size()};
|
||||
ASSERT_EQ(PK11_ImportDERCert(mSlot, &cert1Item, CK_INVALID_HANDLE,
|
||||
cert1Nickname, false),
|
||||
SECSuccess);
|
||||
|
||||
SECItem subjectItem = {siBuffer, nullptr, 0};
|
||||
CERTCertificateList* certificates = nullptr;
|
||||
SECStatus rv =
|
||||
PK11_FindRawCertsWithSubject(mSlot, &subjectItem, &certificates);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
EXPECT_EQ(certificates, nullptr);
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
|
@ -19,6 +19,7 @@
|
|||
'pk11_curve25519_unittest.cc',
|
||||
'pk11_ecdsa_unittest.cc',
|
||||
'pk11_encrypt_derive_unittest.cc',
|
||||
'pk11_find_certs_unittest.cc',
|
||||
'pk11_import_unittest.cc',
|
||||
'pk11_pbkdf2_unittest.cc',
|
||||
'pk11_prf_unittest.cc',
|
||||
|
|
|
@ -12,6 +12,7 @@ CPPSRCS = \
|
|||
|
||||
INCLUDES += \
|
||||
-I$(CORE_DEPTH)/gtests/google_test/gtest/include \
|
||||
-I$(CORE_DEPTH)/gtests/common \
|
||||
-I$(CORE_DEPTH)/cpputil \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
#include <cstdlib>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <codecvt>
|
||||
#endif
|
||||
|
||||
#include "cert.h"
|
||||
#include "certdb.h"
|
||||
#include "nspr.h"
|
||||
|
@ -12,93 +6,13 @@
|
|||
#include "secerr.h"
|
||||
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "util.h"
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
// Given a prefix, attempts to create a unique directory that the user can do
|
||||
// work in without impacting other tests. For example, if given the prefix
|
||||
// "scratch", a directory like "scratch05c17b25" will be created in the current
|
||||
// working directory (or the location specified by NSS_GTEST_WORKDIR, if
|
||||
// defined).
|
||||
// Upon destruction, the implementation will attempt to delete the directory.
|
||||
// However, no attempt is made to first remove files in the directory - the
|
||||
// user is responsible for this. If the directory is not empty, deleting it will
|
||||
// fail.
|
||||
// Statistically, it is technically possible to fail to create a unique
|
||||
// directory name, but this is extremely unlikely given the expected workload of
|
||||
// this implementation.
|
||||
class ScopedUniqueDirectory {
|
||||
public:
|
||||
explicit ScopedUniqueDirectory(const std::string &prefix);
|
||||
|
||||
// NB: the directory must be empty upon destruction
|
||||
~ScopedUniqueDirectory() { assert(rmdir(mPath.c_str()) == 0); }
|
||||
|
||||
const std::string &GetPath() { return mPath; }
|
||||
const std::string &GetUTF8Path() { return mUTF8Path; }
|
||||
|
||||
private:
|
||||
static const int RETRY_LIMIT = 5;
|
||||
static void GenerateRandomName(/*in/out*/ std::string &prefix);
|
||||
static bool TryMakingDirectory(/*in/out*/ std::string &prefix);
|
||||
|
||||
std::string mPath;
|
||||
std::string mUTF8Path;
|
||||
};
|
||||
|
||||
ScopedUniqueDirectory::ScopedUniqueDirectory(const std::string &prefix) {
|
||||
std::string path;
|
||||
const char *workingDirectory = PR_GetEnvSecure("NSS_GTEST_WORKDIR");
|
||||
if (workingDirectory) {
|
||||
path.assign(workingDirectory);
|
||||
}
|
||||
path.append(prefix);
|
||||
for (int i = 0; i < RETRY_LIMIT; i++) {
|
||||
std::string pathCopy(path);
|
||||
// TryMakingDirectory will modify its input. If it fails, we want to throw
|
||||
// away the modified result.
|
||||
if (TryMakingDirectory(pathCopy)) {
|
||||
mPath.assign(pathCopy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(mPath.length() > 0);
|
||||
#if defined(_WIN32)
|
||||
// sqldb always uses UTF-8 regardless of the current system locale.
|
||||
DWORD len =
|
||||
MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), nullptr, 0);
|
||||
std::vector<wchar_t> buf(len, L'\0');
|
||||
MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), buf.data(),
|
||||
buf.size());
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
mUTF8Path = converter.to_bytes(std::wstring(buf.begin(), buf.end()));
|
||||
#else
|
||||
mUTF8Path = mPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ScopedUniqueDirectory::GenerateRandomName(std::string &prefix) {
|
||||
std::stringstream ss;
|
||||
ss << prefix;
|
||||
// RAND_MAX is at least 32767.
|
||||
ss << std::setfill('0') << std::setw(4) << std::hex << rand() << rand();
|
||||
// This will overwrite the value of prefix. This is a little inefficient, but
|
||||
// at least it makes the code simple.
|
||||
ss >> prefix;
|
||||
}
|
||||
|
||||
bool ScopedUniqueDirectory::TryMakingDirectory(std::string &prefix) {
|
||||
GenerateRandomName(prefix);
|
||||
#if defined(_WIN32)
|
||||
return _mkdir(prefix.c_str()) == 0;
|
||||
#else
|
||||
return mkdir(prefix.c_str(), 0777) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
class SoftokenTest : public ::testing::Test {
|
||||
protected:
|
||||
SoftokenTest() : mNSSDBDir("SoftokenTest.d-") {}
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
'<(DEPTH)/lib/dbm/src/src.gyp:dbm',
|
||||
],
|
||||
}],
|
||||
[ 'enable_sslkeylogfile==1', {
|
||||
[ 'enable_sslkeylogfile==1 and sanitizer_flags==0', {
|
||||
'sources': [
|
||||
'ssl_keylog_unittest.cc',
|
||||
],
|
||||
|
|
|
@ -17745,172 +17745,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
|||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "Certinomis - Root CA"
|
||||
#
|
||||
# Issuer: CN=Certinomis - Root CA,OU=0002 433998903,O=Certinomis,C=FR
|
||||
# Serial Number: 1 (0x1)
|
||||
# Subject: CN=Certinomis - Root CA,OU=0002 433998903,O=Certinomis,C=FR
|
||||
# Not Valid Before: Mon Oct 21 09:17:18 2013
|
||||
# Not Valid After : Fri Oct 21 09:17:18 2033
|
||||
# Fingerprint (SHA-256): 2A:99:F5:BC:11:74:B7:3C:BB:1D:62:08:84:E0:1C:34:E5:1C:CB:39:78:DA:12:5F:0E:33:26:88:83:BF:41:58
|
||||
# Fingerprint (SHA1): 9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "Certinomis - Root CA"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\132\061\013\060\011\006\003\125\004\006\023\002\106\122\061
|
||||
\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156
|
||||
\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060
|
||||
\060\060\062\040\064\063\063\071\071\070\071\060\063\061\035\060
|
||||
\033\006\003\125\004\003\023\024\103\145\162\164\151\156\157\155
|
||||
\151\163\040\055\040\122\157\157\164\040\103\101
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\132\061\013\060\011\006\003\125\004\006\023\002\106\122\061
|
||||
\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156
|
||||
\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060
|
||||
\060\060\062\040\064\063\063\071\071\070\071\060\063\061\035\060
|
||||
\033\006\003\125\004\003\023\024\103\145\162\164\151\156\157\155
|
||||
\151\163\040\055\040\122\157\157\164\040\103\101
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\001\001
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\222\060\202\003\172\240\003\002\001\002\002\001\001
|
||||
\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
|
||||
\132\061\013\060\011\006\003\125\004\006\023\002\106\122\061\023
|
||||
\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156\157
|
||||
\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060\060
|
||||
\060\062\040\064\063\063\071\071\070\071\060\063\061\035\060\033
|
||||
\006\003\125\004\003\023\024\103\145\162\164\151\156\157\155\151
|
||||
\163\040\055\040\122\157\157\164\040\103\101\060\036\027\015\061
|
||||
\063\061\060\062\061\060\071\061\067\061\070\132\027\015\063\063
|
||||
\061\060\062\061\060\071\061\067\061\070\132\060\132\061\013\060
|
||||
\011\006\003\125\004\006\023\002\106\122\061\023\060\021\006\003
|
||||
\125\004\012\023\012\103\145\162\164\151\156\157\155\151\163\061
|
||||
\027\060\025\006\003\125\004\013\023\016\060\060\060\062\040\064
|
||||
\063\063\071\071\070\071\060\063\061\035\060\033\006\003\125\004
|
||||
\003\023\024\103\145\162\164\151\156\157\155\151\163\040\055\040
|
||||
\122\157\157\164\040\103\101\060\202\002\042\060\015\006\011\052
|
||||
\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060
|
||||
\202\002\012\002\202\002\001\000\324\314\011\012\054\077\222\366
|
||||
\177\024\236\013\234\232\152\035\100\060\144\375\252\337\016\036
|
||||
\006\133\237\120\205\352\315\215\253\103\147\336\260\372\176\200
|
||||
\226\236\204\170\222\110\326\343\071\356\316\344\131\130\227\345
|
||||
\056\047\230\352\223\250\167\233\112\360\357\164\200\055\353\060
|
||||
\037\265\331\307\200\234\142\047\221\210\360\112\211\335\334\210
|
||||
\346\024\371\325\003\057\377\225\333\275\237\354\054\372\024\025
|
||||
\131\225\012\306\107\174\151\030\271\247\003\371\312\166\251\317
|
||||
\307\157\264\136\005\376\356\301\122\262\165\062\207\354\355\051
|
||||
\146\073\363\112\026\202\366\326\232\333\162\230\351\336\360\305
|
||||
\114\245\253\265\352\001\342\214\056\144\177\144\157\375\243\045
|
||||
\223\213\310\242\016\111\215\064\360\037\354\130\105\056\064\252
|
||||
\204\120\275\347\262\112\023\270\260\017\256\070\135\260\251\033
|
||||
\346\163\311\132\241\331\146\100\252\251\115\246\064\002\255\204
|
||||
\176\262\043\301\373\052\306\147\364\064\266\260\225\152\063\117
|
||||
\161\104\265\255\300\171\063\210\340\277\355\243\240\024\264\234
|
||||
\011\260\012\343\140\276\370\370\146\210\315\133\361\167\005\340
|
||||
\265\163\156\301\175\106\056\216\113\047\246\315\065\012\375\345
|
||||
\115\175\252\052\243\051\307\132\150\004\350\345\326\223\244\142
|
||||
\302\305\346\364\117\306\371\237\032\215\202\111\031\212\312\131
|
||||
\103\072\350\015\062\301\364\114\023\003\157\156\246\077\221\163
|
||||
\313\312\163\157\022\040\213\356\300\202\170\336\113\056\302\111
|
||||
\303\035\355\026\366\044\364\047\033\134\127\061\334\125\356\250
|
||||
\036\157\154\254\342\105\314\127\127\212\165\127\031\340\265\130
|
||||
\231\111\066\061\074\063\001\155\026\112\315\270\052\203\204\206
|
||||
\233\371\140\322\037\155\221\003\323\140\246\325\075\232\335\167
|
||||
\220\075\065\244\237\017\136\365\122\104\151\271\300\272\334\317
|
||||
\175\337\174\331\304\254\206\042\062\274\173\153\221\357\172\370
|
||||
\027\150\260\342\123\125\140\055\257\076\302\203\330\331\011\053
|
||||
\360\300\144\333\207\213\221\314\221\353\004\375\166\264\225\232
|
||||
\346\024\006\033\325\064\035\276\330\377\164\034\123\205\231\340
|
||||
\131\122\112\141\355\210\236\153\111\211\106\176\040\132\331\347
|
||||
\112\345\152\356\322\145\021\103\002\003\001\000\001\243\143\060
|
||||
\141\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
|
||||
\006\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
|
||||
\001\377\060\035\006\003\125\035\016\004\026\004\024\357\221\114
|
||||
\365\245\303\060\350\057\010\352\323\161\042\244\222\150\170\164
|
||||
\331\060\037\006\003\125\035\043\004\030\060\026\200\024\357\221
|
||||
\114\365\245\303\060\350\057\010\352\323\161\042\244\222\150\170
|
||||
\164\331\060\015\006\011\052\206\110\206\367\015\001\001\013\005
|
||||
\000\003\202\002\001\000\176\075\124\332\042\135\032\130\076\073
|
||||
\124\047\272\272\314\310\343\032\152\352\076\371\022\353\126\137
|
||||
\075\120\316\340\352\110\046\046\317\171\126\176\221\034\231\077
|
||||
\320\241\221\034\054\017\117\230\225\131\123\275\320\042\330\210
|
||||
\135\234\067\374\373\144\301\170\214\213\232\140\011\352\325\372
|
||||
\041\137\320\164\145\347\120\305\277\056\271\013\013\255\265\260
|
||||
\027\246\022\214\324\142\170\352\126\152\354\012\322\100\303\074
|
||||
\005\060\076\115\224\267\237\112\003\323\175\047\113\266\376\104
|
||||
\316\372\031\063\032\155\244\102\321\335\314\310\310\327\026\122
|
||||
\203\117\065\224\263\022\125\175\345\342\102\353\344\234\223\011
|
||||
\300\114\133\007\253\307\155\021\240\120\027\224\043\250\265\012
|
||||
\222\017\262\172\301\140\054\070\314\032\246\133\377\362\014\343
|
||||
\252\037\034\334\270\240\223\047\336\143\343\177\041\237\072\345
|
||||
\236\372\340\023\152\165\353\226\134\142\221\224\216\147\123\266
|
||||
\211\370\022\011\313\157\122\133\003\162\206\120\225\010\324\215
|
||||
\207\206\025\037\225\044\330\244\157\232\316\244\235\233\155\322
|
||||
\262\166\006\206\306\126\010\305\353\011\332\066\302\033\133\101
|
||||
\276\141\052\343\160\346\270\246\370\266\132\304\275\041\367\377
|
||||
\252\137\241\154\166\071\146\326\352\114\125\341\000\063\233\023
|
||||
\230\143\311\157\320\001\040\011\067\122\347\014\117\076\315\274
|
||||
\365\137\226\047\247\040\002\225\340\056\350\007\101\005\037\025
|
||||
\156\326\260\344\031\340\017\002\223\000\047\162\305\213\321\124
|
||||
\037\135\112\303\100\227\176\125\246\174\301\063\004\024\001\035
|
||||
\111\040\151\013\031\223\235\156\130\042\367\100\014\106\014\043
|
||||
\143\363\071\322\177\166\121\247\364\310\241\361\014\166\042\043
|
||||
\106\122\051\055\342\243\101\007\126\151\230\322\005\011\274\151
|
||||
\307\132\141\315\217\201\140\025\115\200\335\220\342\175\304\120
|
||||
\362\214\073\156\112\307\306\346\200\053\074\201\274\021\200\026
|
||||
\020\047\327\360\315\077\171\314\163\052\303\176\123\221\326\156
|
||||
\370\365\363\307\320\121\115\216\113\245\133\346\031\027\073\326
|
||||
\201\011\334\042\334\356\216\271\304\217\123\341\147\273\063\270
|
||||
\210\025\106\317\355\151\065\377\165\015\106\363\316\161\341\305
|
||||
\153\206\102\006\271\101
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
|
||||
# Trust for "Certinomis - Root CA"
|
||||
# Issuer: CN=Certinomis - Root CA,OU=0002 433998903,O=Certinomis,C=FR
|
||||
# Serial Number: 1 (0x1)
|
||||
# Subject: CN=Certinomis - Root CA,OU=0002 433998903,O=Certinomis,C=FR
|
||||
# Not Valid Before: Mon Oct 21 09:17:18 2013
|
||||
# Not Valid After : Fri Oct 21 09:17:18 2033
|
||||
# Fingerprint (SHA-256): 2A:99:F5:BC:11:74:B7:3C:BB:1D:62:08:84:E0:1C:34:E5:1C:CB:39:78:DA:12:5F:0E:33:26:88:83:BF:41:58
|
||||
# Fingerprint (SHA1): 9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "Certinomis - Root CA"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\235\160\273\001\245\244\240\030\021\056\367\034\001\271\062\305
|
||||
\064\347\210\250
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\024\012\375\215\250\050\265\070\151\333\126\176\141\042\003\077
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\132\061\013\060\011\006\003\125\004\006\023\002\106\122\061
|
||||
\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156
|
||||
\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060
|
||||
\060\060\062\040\064\063\063\071\071\070\071\060\063\061\035\060
|
||||
\033\006\003\125\004\003\023\024\103\145\162\164\151\156\157\155
|
||||
\151\163\040\055\040\122\157\157\164\040\103\101
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\001\001
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "OISTE WISeKey Global Root GB CA"
|
||||
#
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
* It's recommend to switch back to 0 after having reached version 98/99.
|
||||
*/
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 32
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION "2.32"
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 34
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION "2.34"
|
||||
|
||||
/* These version numbers detail the semantic changes to the ckfw engine. */
|
||||
#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
#include "seccomon.h" /* Required for RSA and DSA. */
|
||||
#include "secerr.h"
|
||||
#include "prtypes.h"
|
||||
#include "secitem.h"
|
||||
#include "pkcs11t.h"
|
||||
|
||||
#include "ec.h" /* Required for ECDSA */
|
||||
#include "ec.h" /* Required for EC */
|
||||
|
||||
/*
|
||||
* different platforms have different ways of calling and initial entry point
|
||||
|
@ -288,6 +290,8 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
/* AES Known Plaintext (128-bits). (blocksize is 128-bits) */
|
||||
static const PRUint8 aes_known_plaintext[] = { "NetscapeepacsteN" };
|
||||
|
||||
static const PRUint8 aes_gcm_known_aad[] = { "MozillaallizoM" };
|
||||
|
||||
/* AES Known Ciphertext (128-bit key). */
|
||||
static const PRUint8 aes_ecb128_known_ciphertext[] = {
|
||||
0x3c, 0xa5, 0x96, 0xf3, 0x34, 0x6a, 0x96, 0xc1,
|
||||
|
@ -299,6 +303,13 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0x15, 0x54, 0x14, 0x1d, 0x4e, 0xd8, 0xd5, 0xea
|
||||
};
|
||||
|
||||
static const PRUint8 aes_gcm128_known_ciphertext[] = {
|
||||
0x63, 0xf4, 0x95, 0x28, 0xe6, 0x78, 0xee, 0x6e,
|
||||
0x4f, 0xe0, 0xfc, 0x8d, 0xd7, 0xa2, 0xb1, 0xff,
|
||||
0x0c, 0x97, 0x1b, 0x0a, 0xdd, 0x97, 0x75, 0xed,
|
||||
0x8b, 0xde, 0xbf, 0x16, 0x5e, 0x57, 0x6b, 0x4f
|
||||
};
|
||||
|
||||
/* AES Known Ciphertext (192-bit key). */
|
||||
static const PRUint8 aes_ecb192_known_ciphertext[] = {
|
||||
0xa0, 0x18, 0x62, 0xed, 0x88, 0x19, 0xcb, 0x62,
|
||||
|
@ -310,6 +321,13 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0x07, 0xbc, 0x43, 0x2f, 0x6d, 0xad, 0x29, 0xe1
|
||||
};
|
||||
|
||||
static const PRUint8 aes_gcm192_known_ciphertext[] = {
|
||||
0xc1, 0x0b, 0x92, 0x1d, 0x68, 0x21, 0xf4, 0x25,
|
||||
0x41, 0x61, 0x20, 0x2d, 0x59, 0x7f, 0x53, 0xde,
|
||||
0x93, 0x39, 0xab, 0x09, 0x76, 0x41, 0x57, 0x2b,
|
||||
0x90, 0x2e, 0x44, 0xbb, 0x52, 0x03, 0xe9, 0x07
|
||||
};
|
||||
|
||||
/* AES Known Ciphertext (256-bit key). */
|
||||
static const PRUint8 aes_ecb256_known_ciphertext[] = {
|
||||
0xdb, 0xa6, 0x52, 0x01, 0x8a, 0x70, 0xae, 0x66,
|
||||
|
@ -321,18 +339,29 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0xc5, 0xc5, 0x68, 0x71, 0x6e, 0x34, 0x40, 0x16
|
||||
};
|
||||
|
||||
static const PRUint8 aes_gcm256_known_ciphertext[] = {
|
||||
0x5d, 0x9e, 0xd2, 0xa2, 0x74, 0x9c, 0xd9, 0x1c,
|
||||
0xd1, 0xc9, 0xee, 0x5d, 0xb6, 0xf2, 0xc9, 0xb6,
|
||||
0x79, 0x27, 0x53, 0x02, 0xa3, 0xdc, 0x22, 0xce,
|
||||
0xf4, 0xb0, 0xc1, 0x8c, 0x86, 0x51, 0xf5, 0xa1
|
||||
};
|
||||
|
||||
const PRUint8 *aes_ecb_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext : aes_ecb256_known_ciphertext;
|
||||
|
||||
const PRUint8 *aes_cbc_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cbc128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cbc192_known_ciphertext : aes_cbc256_known_ciphertext;
|
||||
|
||||
const PRUint8 *aes_gcm_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_gcm128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_gcm192_known_ciphertext : aes_gcm256_known_ciphertext;
|
||||
|
||||
/* AES variables. */
|
||||
PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH];
|
||||
PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
|
||||
PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH * 2];
|
||||
PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH * 2];
|
||||
AESContext *aes_context;
|
||||
unsigned int aes_bytes_encrypted;
|
||||
unsigned int aes_bytes_decrypted;
|
||||
CK_GCM_PARAMS gcmParams;
|
||||
SECStatus aes_status;
|
||||
|
||||
/*check if aes_key_size is 128, 192, or 256 bits */
|
||||
|
@ -455,6 +484,69 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
return (SECFailure);
|
||||
}
|
||||
|
||||
/******************************************************/
|
||||
/* AES-GCM Single-Round Known Answer Encryption Test. */
|
||||
/******************************************************/
|
||||
|
||||
gcmParams.pIv = (PRUint8 *)aes_cbc_known_initialization_vector;
|
||||
gcmParams.ulIvLen = FIPS_AES_BLOCK_SIZE;
|
||||
gcmParams.pAAD = (PRUint8 *)aes_gcm_known_aad;
|
||||
gcmParams.ulAADLen = sizeof(aes_gcm_known_aad);
|
||||
gcmParams.ulTagBits = FIPS_AES_BLOCK_SIZE * 8;
|
||||
aes_context = AES_CreateContext(aes_known_key,
|
||||
(PRUint8 *)&gcmParams,
|
||||
NSS_AES_GCM, PR_TRUE, aes_key_size,
|
||||
FIPS_AES_BLOCK_SIZE);
|
||||
|
||||
if (aes_context == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
aes_status = AES_Encrypt(aes_context, aes_computed_ciphertext,
|
||||
&aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH * 2,
|
||||
aes_known_plaintext,
|
||||
FIPS_AES_DECRYPT_LENGTH);
|
||||
|
||||
AES_DestroyContext(aes_context, PR_TRUE);
|
||||
|
||||
if ((aes_status != SECSuccess) ||
|
||||
(aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH * 2) ||
|
||||
(PORT_Memcmp(aes_computed_ciphertext, aes_gcm_known_ciphertext,
|
||||
FIPS_AES_ENCRYPT_LENGTH * 2) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
/******************************************************/
|
||||
/* AES-GCM Single-Round Known Answer Decryption Test. */
|
||||
/******************************************************/
|
||||
|
||||
aes_context = AES_CreateContext(aes_known_key,
|
||||
(PRUint8 *)&gcmParams,
|
||||
NSS_AES_GCM, PR_FALSE, aes_key_size,
|
||||
FIPS_AES_BLOCK_SIZE);
|
||||
|
||||
if (aes_context == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
aes_status = AES_Decrypt(aes_context, aes_computed_plaintext,
|
||||
&aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH * 2,
|
||||
aes_gcm_known_ciphertext,
|
||||
FIPS_AES_ENCRYPT_LENGTH * 2);
|
||||
|
||||
AES_DestroyContext(aes_context, PR_TRUE);
|
||||
|
||||
if ((aes_status != SECSuccess) ||
|
||||
(aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
|
||||
(PORT_Memcmp(aes_computed_plaintext, aes_known_plaintext,
|
||||
FIPS_AES_DECRYPT_LENGTH) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
|
@ -1094,7 +1186,7 @@ freebl_fips_ECDSA_Test(ECParams *ecparams,
|
|||
"Firefox and ThunderBird are awesome!"
|
||||
};
|
||||
|
||||
unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */
|
||||
unsigned char sha256[SHA256_LENGTH]; /* SHA-256 hash (256 bits) */
|
||||
unsigned char sig[2 * MAX_ECKEY_LEN];
|
||||
SECItem signature, digest;
|
||||
ECPrivateKey *ecdsa_private_key = NULL;
|
||||
|
@ -1136,13 +1228,13 @@ freebl_fips_ECDSA_Test(ECParams *ecparams,
|
|||
/* ECDSA Single-Round Known Answer Signature Test. */
|
||||
/***************************************************/
|
||||
|
||||
ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg);
|
||||
ecdsaStatus = SHA256_HashBuf(sha256, msg, sizeof msg);
|
||||
if (ecdsaStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
digest.type = siBuffer;
|
||||
digest.data = sha1;
|
||||
digest.len = SHA1_LENGTH;
|
||||
digest.data = sha256;
|
||||
digest.len = SHA256_LENGTH;
|
||||
|
||||
memset(sig, 0, sizeof sig);
|
||||
signature.type = siBuffer;
|
||||
|
@ -1181,10 +1273,83 @@ loser:
|
|||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_ECDSA_PowerUpSelfTest()
|
||||
freebl_fips_ECDH_Test(ECParams *ecparams)
|
||||
{
|
||||
|
||||
/* ECDSA Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */
|
||||
/* ECDH Known result (reused old CAVS vector) */
|
||||
static const PRUint8 ecdh_known_pub_key_1[] = {
|
||||
EC_POINT_FORM_UNCOMPRESSED,
|
||||
/* pubX */
|
||||
0x16, 0x81, 0x32, 0x86, 0xc8, 0xe4, 0x3a, 0x1f,
|
||||
0x5d, 0xe3, 0x06, 0x22, 0x8b, 0x99, 0x14, 0x25,
|
||||
0xf7, 0x9c, 0x5b, 0x1e, 0x96, 0x84, 0x85, 0x3b,
|
||||
0x17, 0xfe, 0xf3, 0x1c, 0x0e, 0xed, 0xc4, 0xce,
|
||||
/* pubY */
|
||||
0x7a, 0x44, 0xfe, 0xbd, 0x91, 0x71, 0x7d, 0x73,
|
||||
0xd9, 0x45, 0xea, 0xae, 0x66, 0x78, 0xfa, 0x6e,
|
||||
0x46, 0xcd, 0xfa, 0x95, 0x15, 0x47, 0x62, 0x5d,
|
||||
0xbb, 0x1b, 0x9f, 0xe6, 0x39, 0xfc, 0xfd, 0x47
|
||||
};
|
||||
static const PRUint8 ecdh_known_priv_key_2[] = {
|
||||
0xb4, 0x2a, 0xe3, 0x69, 0x19, 0xec, 0xf0, 0x42,
|
||||
0x6d, 0x45, 0x8c, 0x94, 0x4a, 0x26, 0xa7, 0x5c,
|
||||
0xea, 0x9d, 0xd9, 0x0f, 0x59, 0xe0, 0x1a, 0x9d,
|
||||
0x7c, 0xb7, 0x1c, 0x04, 0x53, 0xb8, 0x98, 0x5a
|
||||
};
|
||||
static const PRUint8 ecdh_known_hash_result[] = {
|
||||
0x16, 0xf3, 0x85, 0xa2, 0x41, 0xf3, 0x7f, 0xc4,
|
||||
0x0b, 0x56, 0x47, 0xee, 0xa7, 0x74, 0xb9, 0xdb,
|
||||
0xe1, 0xfa, 0x22, 0xe9, 0x04, 0xf1, 0xb6, 0x12,
|
||||
0x4b, 0x44, 0x8a, 0xbb, 0xbc, 0x08, 0x2b, 0xa7,
|
||||
};
|
||||
|
||||
SECItem ecdh_priv_2, ecdh_pub_1;
|
||||
SECItem ZZ = { 0, 0, 0 };
|
||||
SECStatus ecdhStatus = SECSuccess;
|
||||
PRUint8 computed_hash_result[HASH_LENGTH_MAX];
|
||||
|
||||
ecdh_priv_2.data = (PRUint8 *)ecdh_known_priv_key_2;
|
||||
ecdh_priv_2.len = sizeof(ecdh_known_priv_key_2);
|
||||
ecdh_pub_1.data = (PRUint8 *)ecdh_known_pub_key_1;
|
||||
ecdh_pub_1.len = sizeof(ecdh_known_pub_key_1);
|
||||
|
||||
/* Generates a new EC key pair. The private key is a supplied
|
||||
* random value (in seed) and the public key is the result of
|
||||
* performing a scalar point multiplication of that value with
|
||||
* the curve's base point.
|
||||
*/
|
||||
ecdhStatus = ECDH_Derive(&ecdh_pub_1, ecparams, &ecdh_priv_2, PR_FALSE, &ZZ);
|
||||
if (ecdhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
ecdhStatus = SHA256_HashBuf(computed_hash_result, ZZ.data, ZZ.len);
|
||||
if (ecdhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (PORT_Memcmp(computed_hash_result, ecdh_known_hash_result,
|
||||
sizeof(ecdh_known_hash_result)) != 0) {
|
||||
ecdhStatus = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (ZZ.data) {
|
||||
SECITEM_FreeItem(&ZZ, PR_FALSE);
|
||||
}
|
||||
|
||||
if (ecdhStatus != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_EC_PowerUpSelfTest()
|
||||
{
|
||||
|
||||
/* EC Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */
|
||||
static const unsigned char p256_prime[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
|
@ -1217,7 +1382,7 @@ freebl_fips_ECDSA_PowerUpSelfTest()
|
|||
static const unsigned char p256_encoding[] = {
|
||||
0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
|
||||
};
|
||||
static const ECParams ecdsa_known_P256_Params = {
|
||||
static const ECParams ec_known_P256_Params = {
|
||||
NULL, ec_params_named, /* arena, type */
|
||||
/* fieldID */
|
||||
{ 256, ec_field_GFp, /* size and type */
|
||||
|
@ -1250,10 +1415,10 @@ freebl_fips_ECDSA_PowerUpSelfTest()
|
|||
0x9d, 0x37, 0x4b, 0x1c, 0xdc, 0x35, 0x90, 0xff,
|
||||
0x1a, 0x2d, 0x98, 0x95, 0x1b, 0x2f, 0xeb, 0x7f,
|
||||
0xbb, 0x81, 0xca, 0xc0, 0x69, 0x75, 0xea, 0xc5,
|
||||
0x59, 0x6a, 0x62, 0x49, 0x3d, 0x50, 0xc9, 0xe1,
|
||||
0x27, 0x3b, 0xff, 0x9b, 0x13, 0x66, 0x67, 0xdd,
|
||||
0x7d, 0xd1, 0x0d, 0x2d, 0x7c, 0x44, 0x04, 0x1b,
|
||||
0x16, 0x21, 0x12, 0xc5, 0xcb, 0xbd, 0x9e, 0x75
|
||||
0xa7, 0xd2, 0x20, 0xdd, 0x45, 0xf9, 0x2b, 0xdd,
|
||||
0xda, 0x98, 0x99, 0x5b, 0x1c, 0x02, 0x3a, 0x27,
|
||||
0x8b, 0x7d, 0xb6, 0xed, 0x0e, 0xe0, 0xa7, 0xac,
|
||||
0xaa, 0x36, 0x2c, 0xfa, 0x1a, 0xdf, 0x0d, 0xe1,
|
||||
};
|
||||
|
||||
ECParams ecparams;
|
||||
|
@ -1261,13 +1426,18 @@ freebl_fips_ECDSA_PowerUpSelfTest()
|
|||
SECStatus rv;
|
||||
|
||||
/* ECDSA GF(p) prime field curve test */
|
||||
ecparams = ecdsa_known_P256_Params;
|
||||
ecparams = ec_known_P256_Params;
|
||||
rv = freebl_fips_ECDSA_Test(&ecparams,
|
||||
ecdsa_known_P256_signature,
|
||||
sizeof ecdsa_known_P256_signature);
|
||||
if (rv != SECSuccess) {
|
||||
return (SECFailure);
|
||||
}
|
||||
/* ECDH GF(p) prime field curve test */
|
||||
rv = freebl_fips_ECDH_Test(&ecparams);
|
||||
if (rv != SECSuccess) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
@ -1417,6 +1587,138 @@ freebl_fips_DSA_PowerUpSelfTest(void)
|
|||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_DH_PowerUpSelfTest(void)
|
||||
{
|
||||
/* DH Known P (2048-bits) */
|
||||
static const PRUint8 dh_known_P[] = {
|
||||
0xc2, 0x79, 0xbb, 0x76, 0x32, 0x0d, 0x43, 0xfd,
|
||||
0x1b, 0x8c, 0xa2, 0x3c, 0x00, 0xdd, 0x6d, 0xef,
|
||||
0xf8, 0x1a, 0xd9, 0xc1, 0xa2, 0xf5, 0x73, 0x2b,
|
||||
0xdb, 0x1a, 0x3e, 0x84, 0x90, 0xeb, 0xe7, 0x8e,
|
||||
0x5f, 0x5c, 0x6b, 0xb6, 0x61, 0x89, 0xd1, 0x03,
|
||||
0xb0, 0x5f, 0x91, 0xe4, 0xd2, 0x82, 0x90, 0xfc,
|
||||
0x3c, 0x49, 0x69, 0x59, 0xc1, 0x51, 0x6a, 0x85,
|
||||
0x71, 0xe7, 0x5d, 0x72, 0x5a, 0x45, 0xad, 0x01,
|
||||
0x6f, 0x82, 0xae, 0xec, 0x91, 0x08, 0x2e, 0x7c,
|
||||
0x64, 0x93, 0x46, 0x1c, 0x68, 0xef, 0xc2, 0x03,
|
||||
0x28, 0x1d, 0x75, 0x3a, 0xeb, 0x9c, 0x46, 0xf0,
|
||||
0xc9, 0xdb, 0x99, 0x95, 0x13, 0x66, 0x4d, 0xd5,
|
||||
0x1a, 0x78, 0x92, 0x51, 0x89, 0x72, 0x28, 0x7f,
|
||||
0x20, 0x70, 0x41, 0x49, 0xa2, 0x86, 0xe9, 0xf9,
|
||||
0x78, 0x5f, 0x8d, 0x2e, 0x5d, 0xfa, 0xdb, 0x57,
|
||||
0xd4, 0x71, 0xdf, 0x66, 0xe3, 0x9e, 0x88, 0x70,
|
||||
0xa4, 0x21, 0x44, 0x6a, 0xc7, 0xae, 0x30, 0x2c,
|
||||
0x9c, 0x1f, 0x91, 0x57, 0xc8, 0x24, 0x34, 0x2d,
|
||||
0x7a, 0x4a, 0x43, 0xc2, 0x5f, 0xab, 0x64, 0x2e,
|
||||
0xaa, 0x28, 0x32, 0x95, 0x42, 0x7b, 0xa0, 0xcc,
|
||||
0xdf, 0xfd, 0x22, 0xc8, 0x56, 0x84, 0xc1, 0x62,
|
||||
0x15, 0xb2, 0x77, 0x86, 0x81, 0xfc, 0xa5, 0x12,
|
||||
0x3c, 0xca, 0x28, 0x17, 0x8f, 0x03, 0x16, 0x6e,
|
||||
0xb8, 0x24, 0xfa, 0x1b, 0x15, 0x02, 0xfd, 0x8b,
|
||||
0xb6, 0x0a, 0x1a, 0xf7, 0x47, 0x41, 0xc5, 0x2b,
|
||||
0x37, 0x3e, 0xa1, 0xbf, 0x68, 0xda, 0x1c, 0x55,
|
||||
0x44, 0xc3, 0xee, 0xa1, 0x63, 0x07, 0x11, 0x3b,
|
||||
0x5f, 0x00, 0x84, 0xb4, 0xc4, 0xe4, 0xa7, 0x97,
|
||||
0x29, 0xf8, 0xce, 0xab, 0xfc, 0x27, 0x3e, 0x34,
|
||||
0xe4, 0xc7, 0x81, 0x52, 0x32, 0x0e, 0x27, 0x3c,
|
||||
0xa6, 0x70, 0x3f, 0x4a, 0x54, 0xda, 0xdd, 0x60,
|
||||
0x26, 0xb3, 0x6e, 0x45, 0x26, 0x19, 0x41, 0x6f
|
||||
};
|
||||
|
||||
static const PRUint8 dh_known_Y_1[] = {
|
||||
0xb4, 0xc7, 0x85, 0xba, 0xa6, 0x98, 0xb3, 0x77,
|
||||
0x41, 0x2b, 0xd9, 0x9a, 0x72, 0x90, 0xa4, 0xac,
|
||||
0xc4, 0xf7, 0xc2, 0x23, 0x9a, 0x68, 0xe2, 0x7d,
|
||||
0x3a, 0x54, 0x45, 0x91, 0xc1, 0xd7, 0x8a, 0x17,
|
||||
0x54, 0xd3, 0x37, 0xaa, 0x0c, 0xcd, 0x0b, 0xe2,
|
||||
0xf2, 0x34, 0x0f, 0x17, 0xa8, 0x07, 0x88, 0xaf,
|
||||
0xed, 0xc1, 0x02, 0xd4, 0xdb, 0xdc, 0x0f, 0x22,
|
||||
0x51, 0x23, 0x40, 0xb9, 0x65, 0x6d, 0x39, 0xf4,
|
||||
0xe1, 0x8b, 0x57, 0x7d, 0xb6, 0xd3, 0xf2, 0x6b,
|
||||
0x02, 0xa9, 0x36, 0xf0, 0x0d, 0xe3, 0xdb, 0x9a,
|
||||
0xbf, 0x20, 0x00, 0x4d, 0xec, 0x6f, 0x68, 0x95,
|
||||
0xee, 0x59, 0x4e, 0x3c, 0xb6, 0xda, 0x7b, 0x19,
|
||||
0x08, 0x9a, 0xef, 0x61, 0x43, 0xf5, 0xfb, 0x25,
|
||||
0x70, 0x19, 0xc1, 0x5f, 0x0e, 0x0f, 0x6a, 0x63,
|
||||
0x44, 0xe9, 0xcf, 0x33, 0xce, 0x13, 0x4f, 0x34,
|
||||
0x3c, 0x94, 0x40, 0x8d, 0xf2, 0x65, 0x42, 0xef,
|
||||
0x70, 0x54, 0xdd, 0x5f, 0xc1, 0xd7, 0x0b, 0xa6,
|
||||
0x06, 0xd5, 0xa6, 0x47, 0xae, 0x2c, 0x1f, 0x5a,
|
||||
0xa6, 0xb3, 0xc1, 0x38, 0x3a, 0x3b, 0x60, 0x94,
|
||||
0xa2, 0x95, 0xab, 0xb2, 0x86, 0x82, 0xc5, 0x3b,
|
||||
0xb8, 0x6f, 0x3e, 0x55, 0x86, 0x84, 0xe0, 0x00,
|
||||
0xe5, 0xef, 0xca, 0x5c, 0xec, 0x7e, 0x38, 0x0f,
|
||||
0x82, 0xa2, 0xb1, 0xee, 0x48, 0x1b, 0x32, 0xbb,
|
||||
0x5a, 0x33, 0xa5, 0x01, 0xba, 0xca, 0xa6, 0x64,
|
||||
0x61, 0xb6, 0xe5, 0x5c, 0x0e, 0x5f, 0x2c, 0x66,
|
||||
0x0d, 0x01, 0x6a, 0x20, 0x04, 0x70, 0x68, 0x82,
|
||||
0x93, 0x29, 0x15, 0x3b, 0x7a, 0x06, 0xb2, 0x92,
|
||||
0x61, 0xcd, 0x7e, 0xa4, 0xc1, 0x15, 0x64, 0x3b,
|
||||
0x3c, 0x51, 0x10, 0x4c, 0x87, 0xa6, 0xaf, 0x07,
|
||||
0xce, 0x46, 0x82, 0x75, 0xf3, 0x90, 0xf3, 0x21,
|
||||
0x55, 0x74, 0xc2, 0xe4, 0x96, 0x7d, 0xc3, 0xe6,
|
||||
0x33, 0xa5, 0xc6, 0x51, 0xef, 0xec, 0x90, 0x08
|
||||
};
|
||||
|
||||
static const PRUint8 dh_known_x_2[] = {
|
||||
0x9e, 0x9b, 0xc3, 0x25, 0x53, 0xf9, 0xfc, 0x92,
|
||||
0xb6, 0xae, 0x54, 0x8e, 0x23, 0x4c, 0x94, 0xba,
|
||||
0x41, 0xe6, 0x29, 0x33, 0xb9, 0xdb, 0xff, 0x6d,
|
||||
0xa8, 0xb8, 0x48, 0x49, 0x66, 0x11, 0xa6, 0x13
|
||||
};
|
||||
|
||||
static const PRUint8 dh_known_hash_result[] = {
|
||||
0x93, 0xa2, 0x89, 0x1c, 0x8a, 0xc3, 0x70, 0xbf,
|
||||
0xa7, 0xdf, 0xb6, 0xd7, 0x82, 0xfb, 0x87, 0x81,
|
||||
0x09, 0x47, 0xf3, 0x9f, 0x5a, 0xbf, 0x4f, 0x3f,
|
||||
0x8e, 0x5e, 0x06, 0xca, 0x30, 0xa7, 0xaf, 0x10
|
||||
};
|
||||
|
||||
/* DH variables. */
|
||||
SECStatus dhStatus;
|
||||
SECItem dh_prime;
|
||||
SECItem dh_pub_key_1;
|
||||
SECItem dh_priv_key_2;
|
||||
SECItem ZZ = { 0, 0, 0 };
|
||||
PRUint8 computed_hash_result[HASH_LENGTH_MAX];
|
||||
|
||||
dh_prime.data = (PRUint8 *)dh_known_P;
|
||||
dh_prime.len = sizeof(dh_known_P);
|
||||
dh_pub_key_1.data = (PRUint8 *)dh_known_Y_1;
|
||||
dh_pub_key_1.len = sizeof(dh_known_Y_1);
|
||||
dh_priv_key_2.data = (PRUint8 *)dh_known_x_2;
|
||||
dh_priv_key_2.len = sizeof(dh_known_x_2);
|
||||
|
||||
/* execute the derive */
|
||||
dhStatus = DH_Derive(&dh_pub_key_1, &dh_prime, &dh_priv_key_2, &ZZ, dh_prime.len);
|
||||
if (dhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
dhStatus = SHA256_HashBuf(computed_hash_result, ZZ.data, ZZ.len);
|
||||
if (dhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (PORT_Memcmp(computed_hash_result, dh_known_hash_result,
|
||||
sizeof(dh_known_hash_result)) != 0) {
|
||||
dhStatus = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (ZZ.data) {
|
||||
SECITEM_FreeItem(&ZZ, PR_FALSE);
|
||||
}
|
||||
|
||||
if (dhStatus != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_RNG_PowerUpSelfTest(void)
|
||||
{
|
||||
|
@ -1541,7 +1843,7 @@ freebl_fipsPowerUpSelfTest(unsigned int tests)
|
|||
return rv;
|
||||
|
||||
/* NOTE: RSA can only be tested in full freebl. It requires access to
|
||||
* the locking primitives */
|
||||
* the locking primitives */
|
||||
/* RSA Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_RSA_PowerUpSelfTest();
|
||||
|
||||
|
@ -1554,8 +1856,14 @@ freebl_fipsPowerUpSelfTest(unsigned int tests)
|
|||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* ECDSA Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_ECDSA_PowerUpSelfTest();
|
||||
/* DH Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_DH_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* EC Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_EC_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
|
|
@ -143,6 +143,7 @@ loser:
|
|||
void
|
||||
intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
|
||||
{
|
||||
PORT_Memset(gcm, 0, sizeof(intel_AES_GCMContext));
|
||||
if (freeit) {
|
||||
PORT_Free(gcm);
|
||||
}
|
||||
|
|
|
@ -491,11 +491,11 @@ cleanup:
|
|||
** This implments steps 4 thorough 22 of FIPS 186-3 A.1.2.1 and
|
||||
** steps 16 through 34 of FIPS 186-2 C.6
|
||||
*/
|
||||
#define MAX_ST_SEED_BITS (HASH_LENGTH_MAX * PR_BITS_PER_BYTE)
|
||||
static SECStatus
|
||||
makePrimefromPrimesShaweTaylor(
|
||||
HASH_HashType hashtype, /* selected Hashing algorithm */
|
||||
unsigned int length, /* input. Length of prime in bits. */
|
||||
unsigned int seedlen, /* input seed length in bits */
|
||||
mp_int *c0, /* seed prime */
|
||||
mp_int *q, /* sub prime, can be 1 */
|
||||
mp_int *prime, /* output. */
|
||||
|
@ -557,7 +557,7 @@ makePrimefromPrimesShaweTaylor(
|
|||
old_counter = *prime_gen_counter;
|
||||
/*
|
||||
** Comment: Generate a pseudorandom integer x in the interval
|
||||
** [2**(lenght-1), 2**length].
|
||||
** [2**(length-1), 2**length].
|
||||
**
|
||||
** Step 6/18 x = 0
|
||||
*/
|
||||
|
@ -569,11 +569,10 @@ makePrimefromPrimesShaweTaylor(
|
|||
for (i = 0; i < iterations; i++) {
|
||||
/* is bigger than prime_seed should get to */
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, i,
|
||||
MAX_ST_SEED_BITS, &x[(iterations - i - 1) * hashlen]));
|
||||
seedlen, &x[(iterations - i - 1) * hashlen]));
|
||||
}
|
||||
/* Step 8/20 prime_seed = prime_seed + iterations + 1 */
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS,
|
||||
prime_seed));
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, seedlen, prime_seed));
|
||||
/*
|
||||
** Step 9/21 x = 2 ** (length-1) + x mod 2 ** (length-1)
|
||||
**
|
||||
|
@ -595,7 +594,7 @@ makePrimefromPrimesShaweTaylor(
|
|||
x[offset] = (mask & x[offset]) | bit;
|
||||
/*
|
||||
** Comment: Generate a candidate prime c in the interval
|
||||
** [2**(lenght-1), 2**length].
|
||||
** [2**(length-1), 2**length].
|
||||
**
|
||||
** Step 10 t = ceiling(x/(2q(p0)))
|
||||
** Step 22 t = ceiling(x/(2(c0)))
|
||||
|
@ -624,7 +623,7 @@ step_23:
|
|||
/* t = 2**(length-1) + 2qc0 -1 */
|
||||
CHECK_MPI_OK(mp_add(&two_length_minus_1, &t, &t));
|
||||
/* t = floor((2**(length-1)+2qc0 -1)/2qco)
|
||||
* = ceil(2**(lenght-2)/2qc0) */
|
||||
* = ceil(2**(length-2)/2qc0) */
|
||||
CHECK_MPI_OK(mp_div(&t, &c0_2, &t, NULL));
|
||||
CHECK_MPI_OK(mp_mul(&t, &c0_2, &c));
|
||||
CHECK_MPI_OK(mp_add_d(&c, (mp_digit)1, &c)); /* c= 2tqc0 + 1*/
|
||||
|
@ -645,13 +644,11 @@ step_23:
|
|||
** NOTE: we reuse the x array for 'a' initially.
|
||||
*/
|
||||
for (i = 0; i < iterations; i++) {
|
||||
/* MAX_ST_SEED_BITS is bigger than prime_seed should get to */
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, i,
|
||||
MAX_ST_SEED_BITS, &x[(iterations - i - 1) * hashlen]));
|
||||
seedlen, &x[(iterations - i - 1) * hashlen]));
|
||||
}
|
||||
/* Step 16/28 prime_seed = prime_seed + iterations + 1 */
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS,
|
||||
prime_seed));
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, seedlen, prime_seed));
|
||||
/* Step 17/29 a = 2 + (a mod (c-3)). */
|
||||
CHECK_MPI_OK(mp_read_unsigned_octets(&a, x, iterations * hashlen));
|
||||
CHECK_MPI_OK(mp_sub_d(&c, (mp_digit)3, &z)); /* z = c -3 */
|
||||
|
@ -742,6 +739,7 @@ makePrimefromSeedShaweTaylor(
|
|||
int hashlen = HASH_ResultLen(hashtype);
|
||||
int outlen = hashlen * PR_BITS_PER_BYTE;
|
||||
int offset;
|
||||
int seedlen = input_seed->len * 8; /*seedlen is in bits */
|
||||
unsigned char bit, mask;
|
||||
unsigned char x[HASH_LENGTH_MAX * 2];
|
||||
mp_digit dummy;
|
||||
|
@ -775,7 +773,7 @@ makePrimefromSeedShaweTaylor(
|
|||
goto cleanup;
|
||||
}
|
||||
/* Steps 16-34 */
|
||||
rv = makePrimefromPrimesShaweTaylor(hashtype, length, &c0, &one,
|
||||
rv = makePrimefromPrimesShaweTaylor(hashtype, length, seedlen, &c0, &one,
|
||||
prime, prime_seed, prime_gen_counter);
|
||||
goto cleanup; /* we're done, one way or the other */
|
||||
}
|
||||
|
@ -787,8 +785,7 @@ makePrimefromSeedShaweTaylor(
|
|||
step_5:
|
||||
/* Step 5 c = Hash(prime_seed) xor Hash(prime_seed+1). */
|
||||
CHECK_SEC_OK(HASH_HashBuf(hashtype, x, prime_seed->data, prime_seed->len));
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, 1,
|
||||
MAX_ST_SEED_BITS, &x[hashlen]));
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, 1, seedlen, &x[hashlen]));
|
||||
for (i = 0; i < hashlen; i++) {
|
||||
x[i] = x[i] ^ x[i + hashlen];
|
||||
}
|
||||
|
@ -817,7 +814,7 @@ step_5:
|
|||
/* Step 8 prime_gen_counter = prime_gen_counter + 1 */
|
||||
(*prime_gen_counter)++;
|
||||
/* Step 9 prime_seed = prime_seed + 2 */
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, 2, MAX_ST_SEED_BITS, prime_seed));
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, 2, seedlen, prime_seed));
|
||||
/* Step 10 Perform deterministic primality test on c. For example, since
|
||||
** c is small, it's primality can be tested by trial division, See
|
||||
** See Appendic C.7.
|
||||
|
@ -890,7 +887,8 @@ findQfromSeed(
|
|||
mp_int *Q_, /* output. */
|
||||
unsigned int *qseed_len, /* output */
|
||||
HASH_HashType *hashtypePtr, /* output. Hash uses */
|
||||
pqgGenType *typePtr) /* output. Generation Type used */
|
||||
pqgGenType *typePtr, /* output. Generation Type used */
|
||||
unsigned int *qgen_counter) /* output. q_counter */
|
||||
{
|
||||
HASH_HashType hashtype;
|
||||
SECItem firstseed = { 0, 0, 0 };
|
||||
|
@ -964,6 +962,7 @@ findQfromSeed(
|
|||
*qseed_len = qseed.len;
|
||||
*hashtypePtr = hashtype;
|
||||
*typePtr = FIPS186_3_ST_TYPE;
|
||||
*qgen_counter = count;
|
||||
SECITEM_FreeItem(&qseed, PR_FALSE);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
@ -1390,19 +1389,26 @@ step_5:
|
|||
CHECK_SEC_OK(makePrimefromSeedShaweTaylor(hashtype, (L + 1) / 2 + 1,
|
||||
&qseed, &p0, &pseed, &pgen_counter));
|
||||
/* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L,
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, seedBytes * 8,
|
||||
&p0, &Q, &P, &pseed, &pgen_counter));
|
||||
|
||||
/* combine all the seeds */
|
||||
seed->len = firstseed.len + qseed.len + pseed.len;
|
||||
if ((qseed.len > firstseed.len) || (pseed.len > firstseed.len)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); /* shouldn't happen */
|
||||
goto cleanup;
|
||||
}
|
||||
/* If the seed overflows, then pseed and qseed may have leading zeros which the mpl code clamps.
|
||||
* we want to make sure those are added back in so the individual seed lengths are predictable from
|
||||
* the overall seed length */
|
||||
seed->len = firstseed.len * 3;
|
||||
seed->data = PORT_ArenaZAlloc(verify->arena, seed->len);
|
||||
if (seed->data == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
PORT_Memcpy(seed->data, firstseed.data, firstseed.len);
|
||||
PORT_Memcpy(seed->data + firstseed.len, pseed.data, pseed.len);
|
||||
PORT_Memcpy(seed->data + firstseed.len + pseed.len, qseed.data, qseed.len);
|
||||
counter = 0; /* (qgen_counter << 16) | pgen_counter; */
|
||||
PORT_Memcpy(seed->data + 2 * firstseed.len - pseed.len, pseed.data, pseed.len);
|
||||
PORT_Memcpy(seed->data + 3 * firstseed.len - qseed.len, qseed.data, qseed.len);
|
||||
counter = (qgen_counter << 16) | pgen_counter;
|
||||
|
||||
/* we've generated both P and Q now, skip to generating G */
|
||||
goto generate_G;
|
||||
|
@ -1622,6 +1628,7 @@ PQG_VerifyParams(const PQGParams *params,
|
|||
int j;
|
||||
unsigned int counter_max = 0; /* handle legacy L < 1024 */
|
||||
unsigned int qseed_len;
|
||||
unsigned int qgen_counter_ = 0;
|
||||
SECItem pseed_ = { 0, 0, 0 };
|
||||
HASH_HashType hashtype;
|
||||
pqgGenType type;
|
||||
|
@ -1701,48 +1708,55 @@ PQG_VerifyParams(const PQGParams *params,
|
|||
/* Steps 7-12 are done only if the optional PQGVerify is supplied. */
|
||||
/* continue processing P */
|
||||
/* 7. counter < 4*L */
|
||||
CHECKPARAM((vfy->counter == -1) || (vfy->counter < counter_max));
|
||||
/* 8. g >= N and g < 2*L (g is length of seed in bits) */
|
||||
g = vfy->seed.len * 8;
|
||||
CHECKPARAM(g >= N && g < counter_max / 2);
|
||||
/* step 7 and 8 are delayed until we determine which type of generation
|
||||
* was used */
|
||||
/* 9. Q generated from SEED matches Q in PQGParams. */
|
||||
/* This function checks all possible hash and generation types to
|
||||
* find a Q_ which matches Q. */
|
||||
g = vfy->seed.len * 8;
|
||||
CHECKPARAM(findQfromSeed(L, N, g, &vfy->seed, &Q, &Q_, &qseed_len,
|
||||
&hashtype, &type) == SECSuccess);
|
||||
&hashtype, &type, &qgen_counter_) == SECSuccess);
|
||||
CHECKPARAM(mp_cmp(&Q, &Q_) == 0);
|
||||
/* now we can do steps 7 & 8*/
|
||||
if ((type == FIPS186_1_TYPE) || (type == FIPS186_3_TYPE)) {
|
||||
CHECKPARAM((vfy->counter == -1) || (vfy->counter < counter_max));
|
||||
CHECKPARAM(g >= N && g < counter_max / 2);
|
||||
}
|
||||
if (type == FIPS186_3_ST_TYPE) {
|
||||
SECItem qseed = { 0, 0, 0 };
|
||||
SECItem pseed = { 0, 0, 0 };
|
||||
unsigned int first_seed_len;
|
||||
unsigned int pgen_counter = 0;
|
||||
unsigned int pgen_counter_ = 0;
|
||||
unsigned int qgen_counter = (vfy->counter >> 16) & 0xffff;
|
||||
unsigned int pgen_counter = (vfy->counter) & 0xffff;
|
||||
|
||||
/* extract pseed and qseed from domain_parameter_seed, which is
|
||||
* first_seed || pseed || qseed. qseed is first_seed + small_integer
|
||||
* pseed is qseed + small_integer. This means most of the time
|
||||
* mod the length of first_seed. pseed is qseed + small_integer mod
|
||||
* the length of first_seed. This means most of the time
|
||||
* first_seed.len == qseed.len == pseed.len. Rarely qseed.len and/or
|
||||
* pseed.len will be one greater than first_seed.len, so we can
|
||||
* depend on the fact that
|
||||
* first_seed.len = floor(domain_parameter_seed.len/3).
|
||||
* findQfromSeed returned qseed.len, so we can calculate pseed.len as
|
||||
* pseed.len = domain_parameter_seed.len - first_seed.len - qseed.len
|
||||
* this is probably over kill, since 99.999% of the time they will all
|
||||
* be equal.
|
||||
*
|
||||
* With the lengths, we can now find the offsets;
|
||||
* pseed.len will be smaller because mpi clamps them. pqgGen
|
||||
* automatically adds the zero pad back though, so we can depend
|
||||
* domain_parameter_seed.len to be a multiple of three. We only have
|
||||
* to deal with the fact that the returned seeds from our functions
|
||||
* could be shorter.
|
||||
* first_seed.len = domain_parameter_seed.len/3
|
||||
* We can now find the offsets;
|
||||
* first_seed.data = domain_parameter_seed.data + 0
|
||||
* pseed.data = domain_parameter_seed.data + first_seed.len
|
||||
* qseed.data = domain_parameter_seed.data
|
||||
* + domain_paramter_seed.len - qseed.len
|
||||
*
|
||||
* We deal with pseed possibly having zero pad in the pseed check later.
|
||||
*/
|
||||
first_seed_len = vfy->seed.len / 3;
|
||||
CHECKPARAM(qseed_len < vfy->seed.len);
|
||||
CHECKPARAM(first_seed_len * 8 > N - 1);
|
||||
CHECKPARAM(first_seed_len + qseed_len < vfy->seed.len);
|
||||
CHECKPARAM(first_seed_len * 8 < counter_max / 2);
|
||||
CHECKPARAM(first_seed_len >= qseed_len);
|
||||
qseed.len = qseed_len;
|
||||
qseed.data = vfy->seed.data + vfy->seed.len - qseed.len;
|
||||
pseed.len = vfy->seed.len - (first_seed_len + qseed_len);
|
||||
pseed.len = first_seed_len;
|
||||
pseed.data = vfy->seed.data + first_seed_len;
|
||||
|
||||
/*
|
||||
|
@ -1754,14 +1768,34 @@ PQG_VerifyParams(const PQGParams *params,
|
|||
** (ST_Random_Prime((ceil(length/2)+1, input_seed)
|
||||
*/
|
||||
CHECK_SEC_OK(makePrimefromSeedShaweTaylor(hashtype, (L + 1) / 2 + 1,
|
||||
&qseed, &p0, &pseed_, &pgen_counter));
|
||||
&qseed, &p0, &pseed_, &pgen_counter_));
|
||||
/* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L,
|
||||
&p0, &Q_, &P_, &pseed_, &pgen_counter));
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, first_seed_len * 8,
|
||||
&p0, &Q_, &P_, &pseed_, &pgen_counter_));
|
||||
CHECKPARAM(mp_cmp(&P, &P_) == 0);
|
||||
/* make sure pseed wasn't tampered with (since it is part of
|
||||
* calculating G) */
|
||||
if (pseed.len > pseed_.len) {
|
||||
/* handle the case of zero pad for pseed */
|
||||
int extra = pseed.len - pseed_.len;
|
||||
int i;
|
||||
for (i = 0; i < extra; i++) {
|
||||
if (pseed.data[i] != 0) {
|
||||
*result = SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
pseed.data += extra;
|
||||
pseed.len -= extra;
|
||||
/* the rest is handled in the normal compare below */
|
||||
}
|
||||
CHECKPARAM(SECITEM_CompareItem(&pseed, &pseed_) == SECEqual);
|
||||
if (vfy->counter != -1) {
|
||||
CHECKPARAM(pgen_counter < counter_max);
|
||||
CHECKPARAM(qgen_counter < counter_max);
|
||||
CHECKPARAM((pgen_counter_ == pgen_counter));
|
||||
CHECKPARAM((qgen_counter_ == qgen_counter));
|
||||
}
|
||||
} else if (vfy->counter == -1) {
|
||||
/* If counter is set to -1, we are really only verifying G, skip
|
||||
* the remainder of the checks for P */
|
||||
|
|
|
@ -1032,13 +1032,19 @@ AES_CreateContext(const unsigned char *key, const unsigned char *iv,
|
|||
void
|
||||
AES_DestroyContext(AESContext *cx, PRBool freeit)
|
||||
{
|
||||
void *mem = cx->mem;
|
||||
if (cx->worker_cx && cx->destroy) {
|
||||
(*cx->destroy)(cx->worker_cx, PR_TRUE);
|
||||
cx->worker_cx = NULL;
|
||||
cx->destroy = NULL;
|
||||
}
|
||||
PORT_Memset(cx, 0, sizeof(AESContext));
|
||||
if (freeit) {
|
||||
PORT_Free(cx->mem);
|
||||
PORT_Free(mem);
|
||||
} else {
|
||||
/* if we are not freeing the context, restore mem, We may get called
|
||||
* again to actually free the context */
|
||||
cx->mem = mem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1151,3 +1151,9 @@ CERT_GetCertificateDer;
|
|||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+NSS_3.45 { # NSS 3.45 release
|
||||
;+ global:
|
||||
PK11_FindRawCertsWithSubject;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
/*
|
||||
* This file manages object type indepentent functions.
|
||||
*/
|
||||
#include <limits.h>
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secmod.h"
|
||||
#include "secmodi.h"
|
||||
|
@ -1883,6 +1885,96 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
|
|||
*object_count = -1;
|
||||
return objID;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_FindRawCertsWithSubject(PK11SlotInfo *slot, SECItem *derSubject,
|
||||
CERTCertificateList **results)
|
||||
{
|
||||
if (!slot || !derSubject || !results) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
*results = NULL;
|
||||
|
||||
// derSubject->data may be null. If so, derSubject->len must be 0.
|
||||
if (!derSubject->data && derSubject->len != 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
|
||||
CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
|
||||
CK_ATTRIBUTE subjectTemplate[] = {
|
||||
{ CKA_CERTIFICATE_TYPE, &ckc_x_509, sizeof(ckc_x_509) },
|
||||
{ CKA_CLASS, &cko_certificate, sizeof(cko_certificate) },
|
||||
{ CKA_SUBJECT, derSubject->data, derSubject->len },
|
||||
};
|
||||
int templateCount = sizeof(subjectTemplate) / sizeof(subjectTemplate[0]);
|
||||
int handleCount = 0;
|
||||
CK_OBJECT_HANDLE *handles =
|
||||
pk11_FindObjectsByTemplate(slot, subjectTemplate, templateCount,
|
||||
&handleCount);
|
||||
if (!handles) {
|
||||
// pk11_FindObjectsByTemplate indicates there was an error by setting
|
||||
// handleCount to -1 (and it has set an error with PORT_SetError).
|
||||
if (handleCount == -1) {
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
PORT_Assert(handleCount > 0);
|
||||
if (handleCount <= 0) {
|
||||
PORT_Free(handles);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
if (handleCount > INT_MAX / sizeof(SECItem)) {
|
||||
PORT_Free(handles);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) {
|
||||
PORT_Free(handles);
|
||||
return SECFailure;
|
||||
}
|
||||
CERTCertificateList *rawCertificates =
|
||||
PORT_ArenaNew(arena, CERTCertificateList);
|
||||
if (!rawCertificates) {
|
||||
PORT_Free(handles);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
rawCertificates->arena = arena;
|
||||
rawCertificates->certs = PORT_ArenaNewArray(arena, SECItem, handleCount);
|
||||
if (!rawCertificates->certs) {
|
||||
PORT_Free(handles);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
rawCertificates->len = handleCount;
|
||||
int handleIndex;
|
||||
for (handleIndex = 0; handleIndex < handleCount; handleIndex++) {
|
||||
SECStatus rv =
|
||||
PK11_ReadAttribute(slot, handles[handleIndex], CKA_VALUE, arena,
|
||||
&rawCertificates->certs[handleIndex]);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Free(handles);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
if (!rawCertificates->certs[handleIndex].data) {
|
||||
PORT_Free(handles);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
PORT_Free(handles);
|
||||
*results = rawCertificates;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* given a PKCS #11 object, match it's peer based on the KeyID. searchID
|
||||
* is typically a privateKey or a certificate while the peer is the opposite
|
||||
|
|
|
@ -875,6 +875,17 @@ SECStatus PK11_WriteRawAttribute(PK11ObjectType type, void *object,
|
|||
PK11SlotList *
|
||||
PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg);
|
||||
|
||||
/*
|
||||
* Finds all certificates on the given slot with the given subject distinguished
|
||||
* name and returns them as DER bytes. If no such certificates can be found,
|
||||
* returns SECSuccess and sets *results to NULL. If a failure is encountered
|
||||
* while fetching any of the matching certificates, SECFailure is returned and
|
||||
* *results will be NULL.
|
||||
*/
|
||||
SECStatus
|
||||
PK11_FindRawCertsWithSubject(PK11SlotInfo *slot, SECItem *derSubject,
|
||||
CERTCertificateList **results);
|
||||
|
||||
/**********************************************************************
|
||||
* New functions which are already deprecated....
|
||||
**********************************************************************/
|
||||
|
|
|
@ -4727,6 +4727,13 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
|||
return crv;
|
||||
}
|
||||
|
||||
/* detect trivial signing transforms */
|
||||
if ((signature_length >= pairwise_digest_length) &&
|
||||
(PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
|
||||
PORT_Free(signature);
|
||||
return CKR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
/* Verify the known hash using the public key. */
|
||||
crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
|
||||
if (crv != CKR_OK) {
|
||||
|
@ -7562,14 +7569,14 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
|
||||
case CKM_DH_PKCS_DERIVE: {
|
||||
SECItem derived, dhPublic;
|
||||
SECItem dhPrime, dhValue;
|
||||
SECItem dhPrime, dhSubPrime, dhValue;
|
||||
/* sourceKey - values for the local existing low key */
|
||||
/* get prime and value attributes */
|
||||
crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME);
|
||||
if (crv != SECSuccess)
|
||||
if (crv != CKR_OK)
|
||||
break;
|
||||
crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE);
|
||||
if (crv != SECSuccess) {
|
||||
if (crv != CKR_OK) {
|
||||
PORT_Free(dhPrime.data);
|
||||
break;
|
||||
}
|
||||
|
@ -7577,6 +7584,20 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
dhPublic.data = pMechanism->pParameter;
|
||||
dhPublic.len = pMechanism->ulParameterLen;
|
||||
|
||||
/* If the caller bothered to provide Q, use Q to validate
|
||||
* the public key. */
|
||||
crv = sftk_Attribute2SecItem(NULL, &dhSubPrime, sourceKey, CKA_SUBPRIME);
|
||||
if (crv == CKR_OK) {
|
||||
rv = KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime);
|
||||
PORT_Free(dhSubPrime.data);
|
||||
if (rv != SECSuccess) {
|
||||
crv = CKR_ARGUMENTS_BAD;
|
||||
PORT_Free(dhPrime.data);
|
||||
PORT_Free(dhValue.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate private value - oct */
|
||||
rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
|
||||
|
||||
|
@ -7586,6 +7607,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
if (rv == SECSuccess) {
|
||||
sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
|
||||
PORT_ZFree(derived.data, derived.len);
|
||||
crv = CKR_OK;
|
||||
} else
|
||||
crv = CKR_HOST_MEMORY;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче