Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 1521174 - Add some initial S/MIME gtests r=mt
Differential Revision: https://phabricator.services.mozilla.com/D17014

--HG--
extra : rebase_source : dcb36675ef858a789669d7bf25642c477327b63a
extra : amend_source : 2086c0420366268f7c79d4cc5e40c8455e98a6af
  • Loading branch information
jcjones committed Dec 10, 2018
1 parent 8dfd93f commit 00b020a
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 1 deletion.
34 changes: 34 additions & 0 deletions cpputil/scoped_ptrs_smime.h
@@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 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/. */

#ifndef scoped_ptrs_smime_h__
#define scoped_ptrs_smime_h__

#include <memory>
#include "smime.h"

struct ScopedDeleteSmime {
void operator()(NSSCMSMessage* id) { NSS_CMSMessage_Destroy(id); }
};

template <class T>
struct ScopedMaybeDeleteSmime {
void operator()(T* ptr) {
if (ptr) {
ScopedDeleteSmime del;
del(ptr);
}
}
};

#define SCOPED(x) \
typedef std::unique_ptr<x, ScopedMaybeDeleteSmime<x> > Scoped##x

SCOPED(NSSCMSMessage);

#undef SCOPED

#endif // scoped_ptrs_smime_h__
1 change: 1 addition & 0 deletions gtests/manifest.mn
Expand Up @@ -24,6 +24,7 @@ NSS_SRCDIRS = \
cryptohi_gtest \
der_gtest \
pk11_gtest \
smime_gtest \
softoken_gtest \
ssl_gtest \
$(SYSINIT_GTEST) \
Expand Down
43 changes: 43 additions & 0 deletions gtests/smime_gtest/Makefile
@@ -0,0 +1,43 @@
#! gmake
#
# 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/.

#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################

include manifest.mn

#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################

include $(CORE_DEPTH)/coreconf/config.mk

#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################


#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################

include ../common/gtest.mk

#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################

include $(CORE_DEPTH)/coreconf/rules.mk

#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################


#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
22 changes: 22 additions & 0 deletions gtests/smime_gtest/manifest.mn
@@ -0,0 +1,22 @@
#
# 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/.
CORE_DEPTH = ../..
DEPTH = ../..
MODULE = nss

CPPSRCS = \
smime_unittest.cc \
$(NULL)

INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
-I$(CORE_DEPTH)/gtests/common \
-I$(CORE_DEPTH)/cpputil

REQUIRES = nspr gtest

PROGRAM = smime_gtest

EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) $(EXTRA_OBJS) \
$(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX)
30 changes: 30 additions & 0 deletions gtests/smime_gtest/smime_gtest.gyp
@@ -0,0 +1,30 @@
# 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/.
{
'includes': [
'../../coreconf/config.gypi',
'../common/gtest.gypi',
],
'targets': [
{
'target_name': 'smime_gtest',
'type': 'executable',
'sources': [
'smime_unittest.cc',
'<(DEPTH)/gtests/common/gtests.cc'
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
'<(DEPTH)/lib/util/util.gyp:nssutil3',
'<(DEPTH)/lib/nss/nss.gyp:nss3',
'<(DEPTH)/lib/smime/smime.gyp:smime',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
]
}
],
'variables': {
'module': 'nss'
}
}
137 changes: 137 additions & 0 deletions gtests/smime_gtest/smime_unittest.cc
@@ -0,0 +1,137 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 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>

#include "gtest/gtest.h"

#include "scoped_ptrs_smime.h"
#include "smime.h"

namespace nss_test {

// See bug 1507174; this is a CMS serialization (RFC 5652) that claims to be
// 12336 bytes long, which ensures CMS validates the streaming decoder's
// incorrect length.
static const unsigned char kHugeLenAsn1[] = {
0x30, 0x82, 0x30, 0x30, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
0x0D, 0x01, 0x07, 0x02, 0xA0, 0x82, 0x02, 0x30, 0x30, 0x30, 0x02,
0x01, 0x30, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x09, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x0B, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05};

// secp256r1 signature with no certs and no attrs
static unsigned char kValidSignature[] = {
0x30, 0x81, 0xFE, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x07, 0x02, 0xA0, 0x81, 0xF0, 0x30, 0x81, 0xED, 0x02, 0x01, 0x01, 0x31,
0x0F, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x01, 0x05, 0x00, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x01, 0x07, 0x01, 0x31, 0x81, 0xC9, 0x30, 0x81, 0xC6, 0x02,
0x01, 0x01, 0x30, 0x5D, 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53,
0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04,
0x0A, 0x0C, 0x18, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20,
0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4C, 0x74, 0x64, 0x02, 0x14, 0x6B, 0x22, 0xCA, 0x91, 0xE0, 0x71, 0x97,
0xEB, 0x45, 0x0D, 0x68, 0xC0, 0xD4, 0xB6, 0xE9, 0x45, 0x38, 0x4C, 0xDD,
0xA3, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x01, 0x05, 0x00, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE,
0x3D, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x48, 0xEB,
0xE6, 0xBA, 0xFC, 0xFD, 0x83, 0xB3, 0xA2, 0xB5, 0x59, 0x35, 0x0C, 0xA1,
0x31, 0x0E, 0x2F, 0xE3, 0x8D, 0x81, 0xD8, 0xF5, 0x33, 0xE4, 0x83, 0x87,
0xB1, 0xFD, 0x43, 0x9D, 0x95, 0x7D, 0x02, 0x21, 0x00, 0xD0, 0x05, 0x0E,
0x05, 0xA6, 0x80, 0x3C, 0x1A, 0xFE, 0x51, 0xFC, 0x4D, 0x1A, 0x25, 0x05,
0x78, 0xB5, 0x42, 0xF5, 0xDE, 0x4E, 0x8A, 0xF8, 0xE3, 0xD8, 0x52, 0xDC,
0x2B, 0x73, 0x80, 0x4A, 0x1A};

// See bug 1507135; this is a CMS signature that contains only the OID
static unsigned char kTruncatedSignature[] = {0x30, 0x0B, 0x06, 0x09, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D,
0x01, 0x07, 0x02};

// secp256r1 signature that's truncated by one byte.
static unsigned char kSlightlyTruncatedSignature[] = {
0x30, 0x81, 0xFE, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x07, 0x02, 0xA0, 0x81, 0xF0, 0x30, 0x81, 0xED, 0x02, 0x01, 0x01, 0x31,
0x0F, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x01, 0x05, 0x00, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x01, 0x07, 0x01, 0x31, 0x81, 0xC9, 0x30, 0x81, 0xC6, 0x02,
0x01, 0x01, 0x30, 0x5D, 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53,
0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04,
0x0A, 0x0C, 0x18, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20,
0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4C, 0x74, 0x64, 0x02, 0x14, 0x6B, 0x22, 0xCA, 0x91, 0xE0, 0x71, 0x97,
0xEB, 0x45, 0x0D, 0x68, 0xC0, 0xD4, 0xB6, 0xE9, 0x45, 0x38, 0x4C, 0xDD,
0xA3, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x01, 0x05, 0x00, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE,
0x3D, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x48, 0xEB,
0xE6, 0xBA, 0xFC, 0xFD, 0x83, 0xB3, 0xA2, 0xB5, 0x59, 0x35, 0x0C, 0xA1,
0x31, 0x0E, 0x2F, 0xE3, 0x8D, 0x81, 0xD8, 0xF5, 0x33, 0xE4, 0x83, 0x87,
0xB1, 0xFD, 0x43, 0x9D, 0x95, 0x7D, 0x02, 0x21, 0x00, 0xD0, 0x05, 0x0E,
0x05, 0xA6, 0x80, 0x3C, 0x1A, 0xFE, 0x51, 0xFC, 0x4D, 0x1A, 0x25, 0x05,
0x78, 0xB5, 0x42, 0xF5, 0xDE, 0x4E, 0x8A, 0xF8, 0xE3, 0xD8, 0x52, 0xDC,
0x2B, 0x73, 0x80, 0x4A};

class SMimeTest : public ::testing::Test {};

TEST_F(SMimeTest, InvalidDER) {
PK11SymKey* bulk_key = nullptr;
NSSCMSDecoderContext* dcx =
NSS_CMSDecoder_Start(nullptr, nullptr, nullptr, /* content callback */
nullptr, nullptr, /* password callback */
nullptr, /* key callback */
bulk_key);
ASSERT_NE(nullptr, dcx);
EXPECT_EQ(SECSuccess, NSS_CMSDecoder_Update(
dcx, reinterpret_cast<const char*>(kHugeLenAsn1),
sizeof(kHugeLenAsn1)));
EXPECT_EQ(nullptr, bulk_key);
ASSERT_FALSE(NSS_CMSDecoder_Finish(dcx));
}

TEST_F(SMimeTest, IsSignedValid) {
SECItem sig_der_item = {siBuffer, kValidSignature, sizeof(kValidSignature)};

ScopedNSSCMSMessage cms_msg(NSS_CMSMessage_CreateFromDER(
&sig_der_item, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));

ASSERT_TRUE(cms_msg);

ASSERT_TRUE(NSS_CMSMessage_IsSigned(cms_msg.get()));
}

TEST_F(SMimeTest, TruncatedCmsSignature) {
SECItem sig_der_item = {siBuffer, kTruncatedSignature,
sizeof(kTruncatedSignature)};

ScopedNSSCMSMessage cms_msg(NSS_CMSMessage_CreateFromDER(
&sig_der_item, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));

ASSERT_TRUE(cms_msg);

ASSERT_FALSE(NSS_CMSMessage_IsSigned(cms_msg.get()));
}

TEST_F(SMimeTest, SlightlyTruncatedCmsSignature) {
SECItem sig_der_item = {siBuffer, kSlightlyTruncatedSignature,
sizeof(kSlightlyTruncatedSignature)};

ScopedNSSCMSMessage cms_msg(NSS_CMSMessage_CreateFromDER(
&sig_der_item, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));

ASSERT_FALSE(cms_msg);

ASSERT_FALSE(NSS_CMSMessage_IsSigned(cms_msg.get()));
}

TEST_F(SMimeTest, IsSignedNull) {
ASSERT_FALSE(NSS_CMSMessage_IsSigned(nullptr));
}

} // namespace nss_test
1 change: 1 addition & 0 deletions nss.gyp
Expand Up @@ -203,6 +203,7 @@
'gtests/mozpkix_gtest/mozpkix_gtest.gyp:mozpkix_gtest',
'gtests/nss_bogo_shim/nss_bogo_shim.gyp:nss_bogo_shim',
'gtests/pk11_gtest/pk11_gtest.gyp:pk11_gtest',
'gtests/smime_gtest/smime_gtest.gyp:smime_gtest',
'gtests/softoken_gtest/softoken_gtest.gyp:softoken_gtest',
'gtests/ssl_gtest/ssl_gtest.gyp:ssl_gtest',
'gtests/util_gtest/util_gtest.gyp:util_gtest',
Expand Down
2 changes: 1 addition & 1 deletion tests/gtests/gtests.sh
Expand Up @@ -87,7 +87,7 @@ gtest_cleanup()
}

################## main #################################################
GTESTS="${GTESTS:-prng_gtest certhigh_gtest certdb_gtest der_gtest pk11_gtest util_gtest freebl_gtest softoken_gtest sysinit_gtest blake2b_gtest}"
GTESTS="${GTESTS:-prng_gtest certhigh_gtest certdb_gtest der_gtest pk11_gtest util_gtest freebl_gtest softoken_gtest sysinit_gtest blake2b_gtest smime_gtest}"
gtest_init "$0"
gtest_start
gtest_cleanup

0 comments on commit 00b020a

Please sign in to comment.