secasn1decode_unittest.cc (2795B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "gtest/gtest.h" 8 #include "scoped_ptrs_util.h" 9 10 #include "nss.h" 11 #include "prerror.h" 12 #include "secasn1.h" 13 #include "secasn1t.h" 14 #include "secerr.h" 15 #include "secport.h" 16 17 class SECASN1DecodeTest : public ::testing::Test {}; 18 19 struct Item { 20 SECItem value; 21 }; 22 23 const SEC_ASN1Template ItemTemplate[] = { 24 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(struct Item)}, {0}}; 25 26 static const SEC_ASN1Template ItemsTemplate[] = { 27 {SEC_ASN1_SEQUENCE_OF, 0, ItemTemplate}, {0}}; 28 29 struct Container { 30 struct Item** items; 31 }; 32 33 const SEC_ASN1Template ContainerTemplate[] = { 34 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(struct Container)}, 35 {SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT | 0, 36 offsetof(struct Container, items), ItemsTemplate}, 37 {0}}; 38 39 // clang-format off 40 const unsigned char kEndOfContentsInDefiniteLengthContext[] = { 41 0x30, 0x06, 42 0xa0, 0x04, 43 0x30, 0x00, 44 0x00, 0x00, // EOC in definite length context 45 }; 46 // clang-format on 47 48 TEST_F(SECASN1DecodeTest, EndOfContentsInDefiniteLengthContext) { 49 ScopedPLArenaPool pool(PORT_NewArena(1024)); 50 struct Container* decoded = reinterpret_cast<struct Container*>( 51 PORT_ArenaZAlloc(pool.get(), sizeof(struct Container))); 52 SEC_ASN1DecoderContext* ctx = 53 SEC_ASN1DecoderStart(pool.get(), decoded, ContainerTemplate); 54 ASSERT_TRUE(ctx); 55 ASSERT_EQ( 56 SEC_ASN1DecoderUpdate( 57 ctx, 58 reinterpret_cast<const char*>(kEndOfContentsInDefiniteLengthContext), 59 sizeof(kEndOfContentsInDefiniteLengthContext)), 60 SECFailure); 61 ASSERT_EQ(PR_GetError(), SEC_ERROR_BAD_DER); 62 ASSERT_EQ(SECSuccess, SEC_ASN1DecoderFinish(ctx)); 63 } 64 65 // clang-format off 66 const unsigned char kContentsTooShort[] = { 67 0x30, 0x06, 68 0xa0, 0x04, 69 0x30, 0x00, // There should be two more bytes after this 70 }; 71 // clang-format on 72 73 TEST_F(SECASN1DecodeTest, ContentsTooShort) { 74 ScopedPLArenaPool pool(PORT_NewArena(1024)); 75 struct Container* decoded = reinterpret_cast<struct Container*>( 76 PORT_ArenaZAlloc(pool.get(), sizeof(struct Container))); 77 SEC_ASN1DecoderContext* ctx = 78 SEC_ASN1DecoderStart(pool.get(), decoded, ContainerTemplate); 79 ASSERT_TRUE(ctx); 80 ASSERT_EQ(SEC_ASN1DecoderUpdate( 81 ctx, reinterpret_cast<const char*>(kContentsTooShort), 82 sizeof(kContentsTooShort)), 83 SECFailure); 84 ASSERT_EQ(PR_GetError(), SEC_ERROR_BAD_DER); 85 ASSERT_EQ(SECSuccess, SEC_ASN1DecoderFinish(ctx)); 86 }