Bug 1334127 - land NSS 6511e19a2c6c, r=me

--HG--
extra : rebase_source : 966e28d8676669276d9fd01d47315c5cafa4ee24
This commit is contained in:
Franziskus Kiefer 2017-02-28 13:52:02 +01:00
Родитель 24bb9f3ffe
Коммит 0c87943561
35 изменённых файлов: 517 добавлений и 148 удалений

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

@ -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