зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1334127 - land NSS 6511e19a2c6c, r=me
--HG-- extra : rebase_source : 966e28d8676669276d9fd01d47315c5cafa4ee24
This commit is contained in:
Родитель
24bb9f3ffe
Коммит
0c87943561
|
@ -1 +1 @@
|
|||
93b99b0936d3
|
||||
6511e19a2c6c
|
||||
|
|
|
@ -50,7 +50,7 @@ ln -s /usr/include/x86_64-linux-gnu/zconf.h /usr/include
|
|||
|
||||
# Install clang-3.9 into /usr/local/.
|
||||
# FIXME: verify signature
|
||||
curl -L http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz | tar xJv -C /usr/local --strip-components=1
|
||||
curl -L http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz | tar xJv -C /usr/local --strip-components=1
|
||||
|
||||
# Install latest Rust (stable).
|
||||
su worker -c "curl https://sh.rustup.rs -sSf | sh -s -- -y"
|
||||
|
|
|
@ -353,7 +353,6 @@ async function scheduleFuzzing() {
|
|||
// Schedule fuzzing runs.
|
||||
let run_base = merge(base, {parent: task_build, kind: "test"});
|
||||
scheduleFuzzingRun(run_base, "CertDN", "certDN", 4096);
|
||||
scheduleFuzzingRun(run_base, "Hash", "hash", 4096);
|
||||
scheduleFuzzingRun(run_base, "QuickDER", "quickder", 10000);
|
||||
|
||||
// Schedule MPI fuzzing runs.
|
||||
|
|
|
@ -615,11 +615,7 @@ P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
|
|||
}
|
||||
|
||||
if (certlist) {
|
||||
CERTCertificate *cert = NULL;
|
||||
node = CERT_LIST_HEAD(certlist);
|
||||
if (node) {
|
||||
cert = node->cert;
|
||||
}
|
||||
CERTCertificate *cert = CERT_LIST_HEAD(certlist)->cert;
|
||||
if (cert) {
|
||||
slot = cert->slot; /* use the slot from the first matching
|
||||
certificate to create the context . This is for keygen */
|
||||
|
@ -861,6 +857,9 @@ p12u_EnableAllCiphers()
|
|||
SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
|
||||
SEC_PKCS12EnableCipher(PKCS12_DES_56, 1);
|
||||
SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
|
||||
SEC_PKCS12EnableCipher(PKCS12_AES_CBC_128, 1);
|
||||
SEC_PKCS12EnableCipher(PKCS12_AES_CBC_192, 1);
|
||||
SEC_PKCS12EnableCipher(PKCS12_AES_CBC_256, 1);
|
||||
SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -875,6 +875,10 @@ restartHandshakeAfterServerCertIfNeeded(PRFileDesc *fd,
|
|||
|
||||
if (SSL_AuthCertificateComplete(fd, error) != SECSuccess) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
/* restore the original error code, which could be reset by
|
||||
* SSL_AuthCertificateComplete */
|
||||
PORT_SetError(error);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -10,4 +10,3 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ struct ScopedDelete {
|
|||
void operator()(SECItem* item) { SECITEM_FreeItem(item, true); }
|
||||
void operator()(SECKEYPublicKey* key) { SECKEY_DestroyPublicKey(key); }
|
||||
void operator()(SECKEYPrivateKey* key) { SECKEY_DestroyPrivateKey(key); }
|
||||
void operator()(SECKEYPrivateKeyList* list) {
|
||||
SECKEY_DestroyPrivateKeyList(list);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -53,6 +56,7 @@ SCOPED(SECAlgorithmID);
|
|||
SCOPED(SECItem);
|
||||
SCOPED(SECKEYPublicKey);
|
||||
SCOPED(SECKEYPrivateKey);
|
||||
SCOPED(SECKEYPrivateKeyList);
|
||||
|
||||
#undef SCOPED
|
||||
|
||||
|
|
|
@ -112,17 +112,6 @@
|
|||
'fuzz_base',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'nssfuzz-hash',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'hash_target.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'fuzz_base',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'nssfuzz-certDN',
|
||||
'type': 'executable',
|
||||
|
@ -287,7 +276,6 @@
|
|||
'type': 'none',
|
||||
'dependencies': [
|
||||
'nssfuzz-certDN',
|
||||
'nssfuzz-hash',
|
||||
'nssfuzz-pkcs8',
|
||||
'nssfuzz-quickder',
|
||||
'nssfuzz-tls-client',
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[libfuzzer]
|
||||
max_len = 4096
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/* 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 <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "hasht.h"
|
||||
#include "pk11pub.h"
|
||||
#include "secoidt.h"
|
||||
#include "shared.h"
|
||||
|
||||
const std::vector<SECOidTag> algos = {SEC_OID_MD5, SEC_OID_SHA1, SEC_OID_SHA256,
|
||||
SEC_OID_SHA384, SEC_OID_SHA512};
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
uint8_t hashOut[HASH_LENGTH_MAX];
|
||||
|
||||
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
|
||||
assert(db != nullptr);
|
||||
|
||||
// simple hashing.
|
||||
for (auto algo : algos) {
|
||||
assert(PK11_HashBuf(algo, hashOut, data, size) == SECSuccess);
|
||||
}
|
||||
|
||||
// hashing with context.
|
||||
for (auto algo : algos) {
|
||||
unsigned int len = 0;
|
||||
PK11Context *context = PK11_CreateDigestContext(algo);
|
||||
assert(context != nullptr);
|
||||
assert(PK11_DigestBegin(context) == SECSuccess);
|
||||
assert(PK11_DigestFinal(context, hashOut, &len, HASH_LENGTH_MAX) ==
|
||||
SECSuccess);
|
||||
PK11_DestroyContext(context, PR_TRUE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -174,7 +174,7 @@ void TlsConnectTestBase::ClearServerCache() {
|
|||
void TlsConnectTestBase::SetUp() {
|
||||
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
|
||||
SSLInt_ClearSessionTicketKey();
|
||||
SSLInt_SetTicketLifetime(10);
|
||||
SSLInt_SetTicketLifetime(30);
|
||||
ClearStats();
|
||||
Init();
|
||||
}
|
||||
|
|
|
@ -2559,9 +2559,9 @@ CERT_AddCertToListHeadWithData(CERTCertList *certs, CERTCertificate *cert,
|
|||
CERTCertListNode *head;
|
||||
|
||||
head = CERT_LIST_HEAD(certs);
|
||||
|
||||
if (head == NULL)
|
||||
return CERT_AddCertToListTail(certs, cert);
|
||||
if (head == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
|
||||
sizeof(CERTCertListNode));
|
||||
|
|
|
@ -515,28 +515,25 @@ CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
|
|||
{
|
||||
CERTCertList *list;
|
||||
CERTCertificate *cert = NULL;
|
||||
CERTCertListNode *node, *head;
|
||||
CERTCertListNode *node;
|
||||
|
||||
list = CERT_CreateSubjectCertList(NULL, handle, name, 0, PR_FALSE);
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
|
||||
node = head = CERT_LIST_HEAD(list);
|
||||
if (head) {
|
||||
do {
|
||||
if (node->cert &&
|
||||
SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID)) {
|
||||
cert = CERT_DupCertificate(node->cert);
|
||||
goto done;
|
||||
}
|
||||
node = CERT_LIST_NEXT(node);
|
||||
} while (node && head != node);
|
||||
node = CERT_LIST_HEAD(list);
|
||||
while (!CERT_LIST_END(node, list)) {
|
||||
if (node->cert &&
|
||||
SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID)) {
|
||||
cert = CERT_DupCertificate(node->cert);
|
||||
goto done;
|
||||
}
|
||||
node = CERT_LIST_NEXT(node);
|
||||
}
|
||||
PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
|
||||
|
||||
done:
|
||||
if (list) {
|
||||
CERT_DestroyCertList(list);
|
||||
}
|
||||
CERT_DestroyCertList(list);
|
||||
return cert;
|
||||
}
|
||||
|
||||
|
@ -635,8 +632,7 @@ common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
|
|||
if (certlist) {
|
||||
SECStatus rv =
|
||||
CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE);
|
||||
if (SECSuccess == rv &&
|
||||
!CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) {
|
||||
if (SECSuccess == rv && !CERT_LIST_EMPTY(certlist)) {
|
||||
cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert);
|
||||
}
|
||||
CERT_DestroyCertList(certlist);
|
||||
|
|
|
@ -289,7 +289,7 @@ CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
|
|||
goto loser;
|
||||
}
|
||||
|
||||
if (!CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) {
|
||||
if (!CERT_LIST_EMPTY(certList)) {
|
||||
cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
|
||||
}
|
||||
|
||||
|
|
|
@ -232,8 +232,6 @@ ifeq ($(CPU_ARCH),x86)
|
|||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT
|
||||
DEFINES += -DMP_IS_LITTLE_ENDIAN
|
||||
# The floating point ECC code doesn't work on Linux x86 (bug 311432).
|
||||
#ECL_USE_FP = 1
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),arm)
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
|
@ -430,7 +428,6 @@ ifeq ($(CPU_ARCH),sparc)
|
|||
ASFILES = mpv_sparcv8.s montmulfv8.s
|
||||
DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY
|
||||
DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL
|
||||
ECL_USE_FP = 1
|
||||
endif
|
||||
ifdef USE_ABI64_INT
|
||||
# this builds for Sparc v9a pure 64-bit architecture
|
||||
|
@ -443,7 +440,6 @@ ifeq ($(CPU_ARCH),sparc)
|
|||
ASFILES = mpv_sparcv9.s montmulfv9.s
|
||||
DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY
|
||||
DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL
|
||||
ECL_USE_FP = 1
|
||||
endif
|
||||
|
||||
else
|
||||
|
@ -491,16 +487,7 @@ else
|
|||
endif
|
||||
endif
|
||||
endif # Solaris for non-sparc family CPUs
|
||||
endif # target == SunOS
|
||||
|
||||
ifndef NSS_DISABLE_ECC
|
||||
ifdef ECL_USE_FP
|
||||
#enable floating point ECC code
|
||||
DEFINES += -DECL_USE_FP
|
||||
ECL_SRCS += ecp_fp160.c ecp_fp192.c ecp_fp224.c ecp_fp.c
|
||||
ECL_HDRS += ecp_fp.h
|
||||
endif
|
||||
endif
|
||||
endif # target == SunO
|
||||
|
||||
# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support
|
||||
# in GCC 4.6.0.
|
||||
|
|
|
@ -1099,6 +1099,7 @@ PK11_VerifyWithMechanism;
|
|||
;+};
|
||||
;+NSS_3.30 { # NSS 3.30 release
|
||||
;+ global:
|
||||
CERT_CompareAVA;
|
||||
PK11_HasAttributeSet;
|
||||
;+ local:
|
||||
;+ *;
|
||||
|
|
|
@ -690,8 +690,7 @@ PK11_FindCertsFromEmailAddress(const char *email, void *wincx)
|
|||
}
|
||||
|
||||
/* empty list? */
|
||||
if (CERT_LIST_HEAD(cbparam.certList) == NULL ||
|
||||
CERT_LIST_END(CERT_LIST_HEAD(cbparam.certList), cbparam.certList)) {
|
||||
if (CERT_LIST_EMPTY(cbparam.certList)) {
|
||||
CERT_DestroyCertList(cbparam.certList);
|
||||
cbparam.certList = NULL;
|
||||
}
|
||||
|
@ -824,10 +823,6 @@ PK11_FindCertsFromNickname(const char *nickname, void *wincx)
|
|||
nssCertificate_Destroy(c);
|
||||
}
|
||||
}
|
||||
if (certList && CERT_LIST_HEAD(certList) == NULL) {
|
||||
CERT_DestroyCertList(certList);
|
||||
certList = NULL;
|
||||
}
|
||||
/* all the certs have been adopted or freed, free the raw array */
|
||||
nss_ZFreeIf(foundCerts);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "plarena.h"
|
||||
|
||||
#include "blapit.h"
|
||||
#include "seccomon.h"
|
||||
#include "secitem.h"
|
||||
#include "secport.h"
|
||||
|
@ -301,17 +302,49 @@ SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
|
|||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
sec_pkcs5_is_algorithm_v2_aes_algorithm(SECOidTag algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case SEC_OID_AES_128_CBC:
|
||||
case SEC_OID_AES_192_CBC:
|
||||
case SEC_OID_AES_256_CBC:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
sec_pkcs5v2_aes_key_length(SECOidTag algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
/* The key length for the AES-CBC-Pad algorithms are
|
||||
* determined from the undelying cipher algorithm. */
|
||||
case SEC_OID_AES_128_CBC:
|
||||
return AES_128_KEY_LENGTH;
|
||||
case SEC_OID_AES_192_CBC:
|
||||
return AES_192_KEY_LENGTH;
|
||||
case SEC_OID_AES_256_CBC:
|
||||
return AES_256_KEY_LENGTH;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the key length in bytes from a PKCS5 PBE
|
||||
*/
|
||||
int
|
||||
sec_pkcs5v2_key_length(SECAlgorithmID *algid)
|
||||
static int
|
||||
sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId)
|
||||
{
|
||||
SECOidTag algorithm;
|
||||
PLArenaPool *arena = NULL;
|
||||
SEC_PKCS5PBEParameter p5_param;
|
||||
SECStatus rv;
|
||||
int length = -1;
|
||||
SECOidTag cipherAlg = SEC_OID_UNKNOWN;
|
||||
|
||||
algorithm = SECOID_GetAlgorithmTag(algid);
|
||||
/* sanity check, they should all be PBKDF2 here */
|
||||
|
@ -330,7 +363,12 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid)
|
|||
goto loser;
|
||||
}
|
||||
|
||||
if (p5_param.keyLength.data != NULL) {
|
||||
if (cipherAlgId)
|
||||
cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId);
|
||||
|
||||
if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlg)) {
|
||||
length = sec_pkcs5v2_aes_key_length(cipherAlg);
|
||||
} else if (p5_param.keyLength.data != NULL) {
|
||||
length = DER_GetInteger(&p5_param.keyLength);
|
||||
}
|
||||
|
||||
|
@ -375,14 +413,15 @@ SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
|
|||
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
|
||||
return 16;
|
||||
case SEC_OID_PKCS5_PBKDF2:
|
||||
return sec_pkcs5v2_key_length(algid);
|
||||
return sec_pkcs5v2_key_length(algid, NULL);
|
||||
case SEC_OID_PKCS5_PBES2:
|
||||
case SEC_OID_PKCS5_PBMAC1: {
|
||||
sec_pkcs5V2Parameter *pbeV2_param;
|
||||
int length = -1;
|
||||
pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
|
||||
if (pbeV2_param != NULL) {
|
||||
length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId);
|
||||
length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId,
|
||||
&pbeV2_param->cipherAlgId);
|
||||
sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
|
||||
}
|
||||
return length;
|
||||
|
@ -614,6 +653,8 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
|
|||
SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
|
||||
if (hashAlg != SEC_OID_UNKNOWN) {
|
||||
keyLength = HASH_ResultLenByOidTag(hashAlg);
|
||||
} else if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlgorithm)) {
|
||||
keyLength = sec_pkcs5v2_aes_key_length(cipherAlgorithm);
|
||||
} else {
|
||||
CK_MECHANISM_TYPE cryptoMech;
|
||||
cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm);
|
||||
|
|
|
@ -177,6 +177,9 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
|
|||
SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg;
|
||||
PK11SlotInfo *slot;
|
||||
PK11SymKey *bulkKey;
|
||||
SECItem *pwitem;
|
||||
SECItem decodedPwitem = { 0 };
|
||||
SECOidTag algorithm;
|
||||
|
||||
if (!p12dcx) {
|
||||
return NULL;
|
||||
|
@ -189,7 +192,24 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
|
|||
slot = PK11_GetInternalKeySlot();
|
||||
}
|
||||
|
||||
bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem,
|
||||
algorithm = SECOID_GetAlgorithmTag(algid);
|
||||
pwitem = p12dcx->pwitem;
|
||||
|
||||
/* here we assume that the password is already encoded into
|
||||
* BMPString by the caller. if the encryption scheme is not the
|
||||
* one defined in PKCS #12, decode the password back into
|
||||
* UTF-8. */
|
||||
if (!sec_pkcs12_is_pkcs12_pbe_algorithm(algorithm)) {
|
||||
if (!sec_pkcs12_convert_item_to_unicode(NULL, &decodedPwitem,
|
||||
p12dcx->pwitem,
|
||||
PR_TRUE, PR_FALSE, PR_FALSE)) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
pwitem = &decodedPwitem;
|
||||
}
|
||||
|
||||
bulkKey = PK11_PBEKeyGen(slot, algid, pwitem,
|
||||
PR_FALSE, p12dcx->wincx);
|
||||
/* some tokens can't generate PBE keys on their own, generate the
|
||||
* key in the internal slot, and let the Import code deal with it,
|
||||
|
@ -198,7 +218,7 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
|
|||
if (!bulkKey && !PK11_IsInternal(slot)) {
|
||||
PK11_FreeSlot(slot);
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem,
|
||||
bulkKey = PK11_PBEKeyGen(slot, algid, pwitem,
|
||||
PR_FALSE, p12dcx->wincx);
|
||||
}
|
||||
PK11_FreeSlot(slot);
|
||||
|
@ -208,6 +228,10 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
|
|||
PK11_SetSymKeyUserData(bulkKey, p12dcx->pwitem, NULL);
|
||||
}
|
||||
|
||||
if (decodedPwitem.data) {
|
||||
SECITEM_ZfreeItem(&decodedPwitem, PR_FALSE);
|
||||
}
|
||||
|
||||
return bulkKey;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "seccomon.h"
|
||||
#include "secport.h"
|
||||
#include "cert.h"
|
||||
#include "secpkcs5.h"
|
||||
#include "secpkcs7.h"
|
||||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
|
@ -378,19 +379,36 @@ SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
|
|||
safeInfo->itemCount = 0;
|
||||
|
||||
/* create the encrypted safe */
|
||||
safeInfo->cinfo = SEC_PKCS7CreateEncryptedData(privAlg, 0, p12ctxt->pwfn,
|
||||
p12ctxt->pwfnarg);
|
||||
if (!SEC_PKCS5IsAlgorithmPBEAlgTag(privAlg) &&
|
||||
PK11_AlgtagToMechanism(privAlg) == CKM_AES_CBC) {
|
||||
safeInfo->cinfo = SEC_PKCS7CreateEncryptedDataWithPBEV2(SEC_OID_PKCS5_PBES2,
|
||||
privAlg,
|
||||
SEC_OID_UNKNOWN,
|
||||
0,
|
||||
p12ctxt->pwfn,
|
||||
p12ctxt->pwfnarg);
|
||||
} else {
|
||||
safeInfo->cinfo = SEC_PKCS7CreateEncryptedData(privAlg, 0, p12ctxt->pwfn,
|
||||
p12ctxt->pwfnarg);
|
||||
}
|
||||
if (!safeInfo->cinfo) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
safeInfo->arena = p12ctxt->arena;
|
||||
|
||||
/* convert the password to unicode */
|
||||
if (!sec_pkcs12_convert_item_to_unicode(NULL, &uniPwitem, pwitem,
|
||||
PR_TRUE, PR_TRUE, PR_TRUE)) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
if (sec_pkcs12_is_pkcs12_pbe_algorithm(privAlg)) {
|
||||
/* convert the password to unicode */
|
||||
if (!sec_pkcs12_convert_item_to_unicode(NULL, &uniPwitem, pwitem,
|
||||
PR_TRUE, PR_TRUE, PR_TRUE)) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
} else {
|
||||
if (SECITEM_CopyItem(NULL, &uniPwitem, pwitem) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
if (SECITEM_CopyItem(p12ctxt->arena, &safeInfo->pwitem, &uniPwitem) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
|
|
|
@ -949,6 +949,33 @@ sec_pkcs12_convert_item_to_unicode(PLArenaPool *arena, SECItem *dest,
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
sec_pkcs12_is_pkcs12_pbe_algorithm(SECOidTag algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
|
||||
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
|
||||
case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
|
||||
case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
|
||||
case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
|
||||
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
|
||||
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
|
||||
case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
|
||||
case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
|
||||
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
|
||||
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
|
||||
/* those are actually PKCS #5 v1.5 PBEs, but we
|
||||
* historically treat them in the same way as PKCS #12
|
||||
* PBEs */
|
||||
case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
|
||||
case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
|
||||
case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* pkcs 12 templates */
|
||||
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_shroud_chooser =
|
||||
sec_pkcs12_choose_shroud_type;
|
||||
|
|
|
@ -55,4 +55,6 @@ sec_PKCS12ConvertOldSafeToNew(PLArenaPool *arena, PK11SlotInfo *slot,
|
|||
void *wincx, SEC_PKCS12SafeContents *safe,
|
||||
SEC_PKCS12Baggage *baggage);
|
||||
|
||||
extern PRBool sec_pkcs12_is_pkcs12_pbe_algorithm(SECOidTag algorithm);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,9 @@ static pkcs12SuiteMap pkcs12SuiteMaps[] = {
|
|||
{ SEC_OID_RC2_CBC, 128, PKCS12_RC2_CBC_128, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_DES_CBC, 64, PKCS12_DES_56, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_DES_EDE3_CBC, 192, PKCS12_DES_EDE3_168, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_AES_128_CBC, 128, PKCS12_AES_CBC_128, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_AES_192_CBC, 192, PKCS12_AES_CBC_192, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_AES_256_CBC, 256, PKCS12_AES_CBC_256, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_UNKNOWN, 0, PKCS12_NULL, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_UNKNOWN, 0, 0L, PR_FALSE, PR_FALSE }
|
||||
};
|
||||
|
|
|
@ -1245,3 +1245,56 @@ SEC_PKCS7CreateEncryptedData(SECOidTag algorithm, int keysize,
|
|||
|
||||
return cinfo;
|
||||
}
|
||||
|
||||
SEC_PKCS7ContentInfo *
|
||||
SEC_PKCS7CreateEncryptedDataWithPBEV2(SECOidTag pbe_algorithm,
|
||||
SECOidTag cipher_algorithm,
|
||||
SECOidTag prf_algorithm,
|
||||
int keysize,
|
||||
SECKEYGetPasswordKey pwfn, void *pwfn_arg)
|
||||
{
|
||||
SEC_PKCS7ContentInfo *cinfo;
|
||||
SECAlgorithmID *algid;
|
||||
SEC_PKCS7EncryptedData *enc_data;
|
||||
SECStatus rv;
|
||||
|
||||
PORT_Assert(SEC_PKCS5IsAlgorithmPBEAlgTag(pbe_algorithm));
|
||||
|
||||
cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_ENCRYPTED_DATA,
|
||||
PR_FALSE, pwfn, pwfn_arg);
|
||||
if (cinfo == NULL)
|
||||
return NULL;
|
||||
|
||||
enc_data = cinfo->content.encryptedData;
|
||||
algid = &(enc_data->encContentInfo.contentEncAlg);
|
||||
|
||||
SECAlgorithmID *pbe_algid;
|
||||
pbe_algid = PK11_CreatePBEV2AlgorithmID(pbe_algorithm,
|
||||
cipher_algorithm,
|
||||
prf_algorithm,
|
||||
keysize,
|
||||
NSS_PBE_DEFAULT_ITERATION_COUNT,
|
||||
NULL);
|
||||
if (pbe_algid == NULL) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
rv = SECOID_CopyAlgorithmID(cinfo->poolp, algid, pbe_algid);
|
||||
SECOID_DestroyAlgorithmID(pbe_algid, PR_TRUE);
|
||||
}
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
SEC_PKCS7DestroyContentInfo(cinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rv = sec_pkcs7_init_encrypted_content_info(&(enc_data->encContentInfo),
|
||||
cinfo->poolp,
|
||||
SEC_OID_PKCS7_DATA, PR_FALSE,
|
||||
cipher_algorithm, keysize);
|
||||
if (rv != SECSuccess) {
|
||||
SEC_PKCS7DestroyContentInfo(cinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cinfo;
|
||||
}
|
||||
|
|
|
@ -286,6 +286,26 @@ extern SEC_PKCS7ContentInfo *
|
|||
SEC_PKCS7CreateEncryptedData(SECOidTag algorithm, int keysize,
|
||||
SECKEYGetPasswordKey pwfn, void *pwfn_arg);
|
||||
|
||||
/*
|
||||
* Create an empty PKCS7 encrypted content info.
|
||||
*
|
||||
* Similar to SEC_PKCS7CreateEncryptedData(), but this is capable of
|
||||
* creating encrypted content for PKCS #5 v2 algorithms.
|
||||
*
|
||||
* "pbe_algorithm" specifies the PBE algorithm to use.
|
||||
* "cipher_algorithm" specifies the bulk encryption algorithm to use.
|
||||
* "prf_algorithm" specifies the PRF algorithm which pbe_algorithm uses.
|
||||
*
|
||||
* An error results in a return value of NULL and an error set.
|
||||
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
|
||||
*/
|
||||
extern SEC_PKCS7ContentInfo *
|
||||
SEC_PKCS7CreateEncryptedDataWithPBEV2(SECOidTag pbe_algorithm,
|
||||
SECOidTag cipher_algorithm,
|
||||
SECOidTag prf_algorithm,
|
||||
int keysize,
|
||||
SECKEYGetPasswordKey pwfn, void *pwfn_arg);
|
||||
|
||||
/*
|
||||
* All of the following things return SECStatus to signal success or failure.
|
||||
* Failure should have a more specific error status available via
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
#define PKCS12_RC4_128 (CIPHER_FAMILYID_PKCS12 | 0012)
|
||||
#define PKCS12_DES_56 (CIPHER_FAMILYID_PKCS12 | 0021)
|
||||
#define PKCS12_DES_EDE3_168 (CIPHER_FAMILYID_PKCS12 | 0022)
|
||||
#define PKCS12_AES_CBC_128 (CIPHER_FAMILYID_PKCS12 | 0031)
|
||||
#define PKCS12_AES_CBC_192 (CIPHER_FAMILYID_PKCS12 | 0032)
|
||||
#define PKCS12_AES_CBC_256 (CIPHER_FAMILYID_PKCS12 | 0033)
|
||||
|
||||
/* SMIME version numbers are negative, to avoid colliding with SSL versions */
|
||||
#define SMIME_LIBRARY_VERSION_1_0 -0x0100
|
||||
|
|
|
@ -704,9 +704,8 @@ NSSBase64_DecodeBuffer(PLArenaPool *arenaOpt, SECItem *outItemOpt,
|
|||
{
|
||||
SECItem *out_item = NULL;
|
||||
PRUint32 max_out_len = 0;
|
||||
PRUint32 out_len;
|
||||
void *mark = NULL;
|
||||
unsigned char *dummy;
|
||||
unsigned char *dummy = NULL;
|
||||
|
||||
if ((outItemOpt != NULL && outItemOpt->data != NULL) || inLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -717,33 +716,35 @@ NSSBase64_DecodeBuffer(PLArenaPool *arenaOpt, SECItem *outItemOpt,
|
|||
mark = PORT_ArenaMark(arenaOpt);
|
||||
|
||||
max_out_len = PL_Base64MaxDecodedLength(inLen);
|
||||
if (max_out_len == 0) {
|
||||
goto loser;
|
||||
}
|
||||
out_item = SECITEM_AllocItem(arenaOpt, outItemOpt, max_out_len);
|
||||
if (out_item == NULL) {
|
||||
if (arenaOpt != NULL)
|
||||
PORT_ArenaRelease(arenaOpt, mark);
|
||||
return NULL;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
dummy = PL_Base64DecodeBuffer(inStr, inLen, out_item->data,
|
||||
max_out_len, &out_len);
|
||||
max_out_len, &out_item->len);
|
||||
if (dummy == NULL) {
|
||||
if (arenaOpt != NULL) {
|
||||
PORT_ArenaRelease(arenaOpt, mark);
|
||||
if (outItemOpt != NULL) {
|
||||
outItemOpt->data = NULL;
|
||||
outItemOpt->len = 0;
|
||||
}
|
||||
} else {
|
||||
SECITEM_FreeItem(out_item,
|
||||
(outItemOpt == NULL) ? PR_TRUE : PR_FALSE);
|
||||
}
|
||||
return NULL;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (arenaOpt != NULL)
|
||||
if (arenaOpt != NULL) {
|
||||
PORT_ArenaUnmark(arenaOpt, mark);
|
||||
out_item->len = out_len;
|
||||
}
|
||||
return out_item;
|
||||
|
||||
loser:
|
||||
if (arenaOpt != NULL) {
|
||||
PORT_ArenaRelease(arenaOpt, mark);
|
||||
if (outItemOpt != NULL) {
|
||||
outItemOpt->data = NULL;
|
||||
outItemOpt->len = 0;
|
||||
}
|
||||
} else if (dummy == NULL) {
|
||||
SECITEM_FreeItem(out_item, (PRBool)(outItemOpt == NULL));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/* 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 "util.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <prerror.h>
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(WIN32) || defined(_WIN64)
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
static std::string GetPassword(const std::string &prompt) {
|
||||
std::cout << prompt << std::endl;
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
termios oldt;
|
||||
tcgetattr(STDIN_FILENO, &oldt);
|
||||
termios newt = oldt;
|
||||
newt.c_lflag &= ~ECHO;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
#elif defined(WIN32) || defined(_WIN64)
|
||||
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD mode = 0;
|
||||
GetConsoleMode(hStdin, &mode);
|
||||
SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT));
|
||||
#endif
|
||||
|
||||
std::string pw;
|
||||
std::getline(std::cin, pw);
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
#elif defined(WIN32) || defined(_WIN64)
|
||||
SetConsoleMode(hStdin, mode);
|
||||
#endif
|
||||
|
||||
return pw;
|
||||
}
|
||||
|
||||
static char *GetModulePassword(PK11SlotInfo *slot, int retry, void *arg) {
|
||||
if (arg == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PwData *pwData = reinterpret_cast<PwData *>(arg);
|
||||
|
||||
if (retry > 0) {
|
||||
std::cerr << "Incorrect password/PIN entered." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
switch (pwData->source) {
|
||||
case PW_NONE:
|
||||
case PW_FROMFILE:
|
||||
std::cerr << "Password input method not supported." << std::endl;
|
||||
return nullptr;
|
||||
case PW_PLAINTEXT:
|
||||
return PL_strdup(pwData->data);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::cerr << "Password check failed: No password found." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool InitSlotPassword(void) {
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
|
||||
if (slot.get() == nullptr) {
|
||||
std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Enter a password which will be used to encrypt your keys."
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
std::string pw;
|
||||
|
||||
while (true) {
|
||||
pw = GetPassword("Enter new password: ");
|
||||
if (pw == GetPassword("Re-enter password: ")) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::cerr << "Passwords do not match. Try again." << std::endl;
|
||||
}
|
||||
|
||||
SECStatus rv = PK11_InitPin(slot.get(), nullptr, pw.c_str());
|
||||
if (rv != SECSuccess) {
|
||||
std::cerr << "Init db password failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DBLoginIfNeeded(const ScopedPK11SlotInfo &slot) {
|
||||
if (!PK11_NeedLogin(slot.get())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PK11_SetPasswordFunc(&GetModulePassword);
|
||||
std::string pw = GetPassword("Enter your password: ");
|
||||
PwData pwData = {PW_PLAINTEXT, const_cast<char *>(pw.c_str())};
|
||||
SECStatus rv = PK11_Authenticate(slot.get(), true /*loadCerts*/, &pwData);
|
||||
if (rv != SECSuccess) {
|
||||
std::cerr << "Could not authenticate to token "
|
||||
<< PK11_GetTokenName(slot.get()) << ". Failed with error "
|
||||
<< PR_ErrorToName(PR_GetError()) << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string StringToHex(const ScopedSECItem &input) {
|
||||
std::stringstream ss;
|
||||
ss << "0x";
|
||||
for (size_t i = 0; i < input->len; i++) {
|
||||
ss << std::hex << std::setfill('0') << std::setw(2)
|
||||
<< static_cast<int>(input->data[i]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* 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/. */
|
||||
|
||||
#ifndef util_h__
|
||||
#define util_h__
|
||||
|
||||
#include "scoped_ptrs.h"
|
||||
|
||||
#include <secmodt.h>
|
||||
#include <string>
|
||||
|
||||
enum PwDataType { PW_NONE = 0, PW_FROMFILE = 1, PW_PLAINTEXT = 2 };
|
||||
typedef struct {
|
||||
PwDataType source;
|
||||
char *data;
|
||||
} PwData;
|
||||
|
||||
bool InitSlotPassword(void);
|
||||
bool DBLoginIfNeeded(const ScopedPK11SlotInfo &slot);
|
||||
std::string StringToHex(const ScopedSECItem &input);
|
||||
|
||||
#endif // util_h__
|
|
@ -5,6 +5,7 @@
|
|||
#include "dbtool.h"
|
||||
#include "argparse.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fstream>
|
||||
|
@ -17,8 +18,17 @@
|
|||
#include <cert.h>
|
||||
#include <certdb.h>
|
||||
#include <nss.h>
|
||||
#include <prerror.h>
|
||||
#include <prio.h>
|
||||
|
||||
const std::vector<std::string> kCommandArgs({"--create", "--list-certs",
|
||||
"--import-cert", "--list-keys"});
|
||||
|
||||
static bool HasSingleCommandArgument(const ArgParser &parser) {
|
||||
auto pred = [&](const std::string &cmd) { return parser.Has(cmd); };
|
||||
return std::count_if(kCommandArgs.begin(), kCommandArgs.end(), pred) == 1;
|
||||
}
|
||||
|
||||
static std::string PrintFlags(unsigned int flags) {
|
||||
std::stringstream ss;
|
||||
if ((flags & CERTDB_VALID_CA) && !(flags & CERTDB_TRUSTED_CA) &&
|
||||
|
@ -63,19 +73,23 @@ static std::vector<char> ReadFromIstream(std::istream &is) {
|
|||
return certData;
|
||||
}
|
||||
|
||||
static const char *const keyTypeName[] = {"null", "rsa", "dsa", "fortezza",
|
||||
"dh", "kea", "ec"};
|
||||
|
||||
void DBTool::Usage() {
|
||||
std::cerr << "Usage: nss db [--path <directory>]" << std::endl;
|
||||
std::cerr << " --create" << std::endl;
|
||||
std::cerr << " --list-certs" << std::endl;
|
||||
std::cerr << " --import-cert [<path>] --name <name> [--trusts <trusts>]"
|
||||
<< std::endl;
|
||||
std::cerr << " --list-keys" << std::endl;
|
||||
}
|
||||
|
||||
bool DBTool::Run(const std::vector<std::string> &arguments) {
|
||||
ArgParser parser(arguments);
|
||||
|
||||
if (!parser.Has("--create") && !parser.Has("--list-certs") &&
|
||||
!parser.Has("--import-cert")) {
|
||||
if (!HasSingleCommandArgument(parser)) {
|
||||
Usage();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -129,7 +143,12 @@ bool DBTool::Run(const std::vector<std::string> &arguments) {
|
|||
} else if (parser.Has("--import-cert")) {
|
||||
ret = ImportCertificate(parser);
|
||||
} else if (parser.Has("--create")) {
|
||||
std::cout << "DB files created successfully." << std::endl;
|
||||
ret = InitSlotPassword();
|
||||
if (ret) {
|
||||
std::cout << "DB files created successfully." << std::endl;
|
||||
}
|
||||
} else if (parser.Has("--list-keys")) {
|
||||
ret = ListKeys();
|
||||
}
|
||||
|
||||
// shutdown nss
|
||||
|
@ -233,7 +252,7 @@ bool DBTool::ImportCertificate(const ArgParser &parser) {
|
|||
|
||||
ScopedPK11SlotInfo slot = ScopedPK11SlotInfo(PK11_GetInternalKeySlot());
|
||||
if (slot.get() == nullptr) {
|
||||
std::cerr << "Error: Init PK11SlotInfo failed!\n";
|
||||
std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -279,3 +298,72 @@ bool DBTool::ImportCertificate(const ArgParser &parser) {
|
|||
// TODO show information about imported certificate
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DBTool::ListKeys() {
|
||||
ScopedPK11SlotInfo slot = ScopedPK11SlotInfo(PK11_GetInternalKeySlot());
|
||||
if (slot.get() == nullptr) {
|
||||
std::cerr << "Error: Init PK11SlotInfo failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DBLoginIfNeeded(slot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedSECKEYPrivateKeyList list(PK11_ListPrivateKeysInSlot(slot.get()));
|
||||
if (list.get() == nullptr) {
|
||||
std::cerr << "Listing private keys failed with error "
|
||||
<< PR_ErrorToName(PR_GetError()) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SECKEYPrivateKeyListNode *node;
|
||||
int count = 0;
|
||||
for (node = PRIVKEY_LIST_HEAD(list.get());
|
||||
!PRIVKEY_LIST_END(node, list.get()); node = PRIVKEY_LIST_NEXT(node)) {
|
||||
char *keyNameRaw = PK11_GetPrivateKeyNickname(node->key);
|
||||
std::string keyName(keyNameRaw ? "" : keyNameRaw);
|
||||
|
||||
if (keyName.empty()) {
|
||||
ScopedCERTCertificate cert(PK11_GetCertFromPrivateKey(node->key));
|
||||
if (cert.get()) {
|
||||
if (cert->nickname && strlen(cert->nickname) > 0) {
|
||||
keyName = cert->nickname;
|
||||
} else if (cert->emailAddr && strlen(cert->emailAddr) > 0) {
|
||||
keyName = cert->emailAddr;
|
||||
}
|
||||
}
|
||||
if (keyName.empty()) {
|
||||
keyName = "(none)"; // default value
|
||||
}
|
||||
}
|
||||
|
||||
SECKEYPrivateKey *key = node->key;
|
||||
ScopedSECItem keyIDItem(PK11_GetLowLevelKeyIDForPrivateKey(key));
|
||||
if (keyIDItem.get() == nullptr) {
|
||||
std::cerr << "Error: PK11_GetLowLevelKeyIDForPrivateKey failed!"
|
||||
<< std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string keyID = StringToHex(keyIDItem);
|
||||
|
||||
if (count++ == 0) {
|
||||
// print header
|
||||
std::cout << std::left << std::setw(20) << "<key#, key name>"
|
||||
<< std::setw(20) << "key type"
|
||||
<< "key id" << std::endl;
|
||||
}
|
||||
|
||||
std::stringstream leftElem;
|
||||
leftElem << "<" << count << ", " << keyName << ">";
|
||||
std::cout << std::left << std::setw(20) << leftElem.str() << std::setw(20)
|
||||
<< keyTypeName[key->keyType] << keyID << std::endl;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
std::cout << "No keys found." << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ class DBTool {
|
|||
bool PathHasDBFiles(std::string path);
|
||||
void ListCertificates();
|
||||
bool ImportCertificate(const ArgParser& parser);
|
||||
bool ListKeys();
|
||||
};
|
||||
|
||||
#endif // dbtool_h__
|
||||
|
|
|
@ -33,7 +33,6 @@ int main(int argc, char **argv) {
|
|||
std::vector<std::string> arguments(argv + 2, argv + argc);
|
||||
DBTool tool;
|
||||
if (!tool.Run(arguments)) {
|
||||
tool.Usage();
|
||||
exit_code = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
'sources' : [
|
||||
'nss_tool.cc',
|
||||
'common/argparse.cc',
|
||||
'common/util.cc',
|
||||
'db/dbtool.cc',
|
||||
],
|
||||
'include_dirs': [
|
||||
|
|
|
@ -25,7 +25,7 @@ bogo_init()
|
|||
BORING=${BORING:=boringssl}
|
||||
if [ ! -d "$BORING" ]; then
|
||||
git clone -q https://boringssl.googlesource.com/boringssl "$BORING"
|
||||
git -C "$BORING" checkout -q 004bff3a1412fcc6ba168d4295a942f9b1e0866e
|
||||
git -C "$BORING" checkout -q 5ae416528a0e554aa4df91bdb1e03f75bfc03cd0
|
||||
fi
|
||||
|
||||
SCRIPTNAME="bogo.sh"
|
||||
|
|
|
@ -273,12 +273,9 @@ tools_p12_export_list_import_all_pkcs5v2_ciphers()
|
|||
CAMELLIA-256-CBC; do
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Bug 452464 - pk12util -o fails when -C option specifies AES or
|
||||
# Bug 452464 - pk12util -o fails when -C option specifies
|
||||
# Camellia ciphers
|
||||
# FIXME Restore these to the list
|
||||
# AES-128-CBC, \
|
||||
# AES-192-CBC, \
|
||||
# AES-256-CBC, \
|
||||
# CAMELLIA-128-CBC, \
|
||||
# CAMELLIA-192-CBC, \
|
||||
# CAMELLIA-256-CBC, \
|
||||
|
@ -287,6 +284,9 @@ tools_p12_export_list_import_all_pkcs5v2_ciphers()
|
|||
for cert_cipher in \
|
||||
RC2-CBC \
|
||||
DES-EDE3-CBC \
|
||||
AES-128-CBC \
|
||||
AES-192-CBC \
|
||||
AES-256-CBC \
|
||||
null; do
|
||||
export_list_import ${key_cipher} ${cert_cipher}
|
||||
done
|
||||
|
|
Загрузка…
Ссылка в новой задаче