Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
michael@0 | 3 | /* Copyright 2013 Mozilla Foundation |
michael@0 | 4 | * |
michael@0 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
michael@0 | 6 | * you may not use this file except in compliance with the License. |
michael@0 | 7 | * You may obtain a copy of the License at |
michael@0 | 8 | * |
michael@0 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
michael@0 | 10 | * |
michael@0 | 11 | * Unless required by applicable law or agreed to in writing, software |
michael@0 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
michael@0 | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
michael@0 | 14 | * See the License for the specific language governing permissions and |
michael@0 | 15 | * limitations under the License. |
michael@0 | 16 | */ |
michael@0 | 17 | |
michael@0 | 18 | #include "pkixder.h" |
michael@0 | 19 | |
michael@0 | 20 | namespace mozilla { namespace pkix { namespace der { |
michael@0 | 21 | |
michael@0 | 22 | // not inline |
michael@0 | 23 | Result |
michael@0 | 24 | Fail(PRErrorCode errorCode) |
michael@0 | 25 | { |
michael@0 | 26 | PR_SetError(errorCode, 0); |
michael@0 | 27 | return Failure; |
michael@0 | 28 | } |
michael@0 | 29 | |
michael@0 | 30 | // Too complicated to be inline |
michael@0 | 31 | Result |
michael@0 | 32 | ExpectTagAndGetLength(Input& input, uint8_t expectedTag, uint16_t& length) |
michael@0 | 33 | { |
michael@0 | 34 | PR_ASSERT((expectedTag & 0x1F) != 0x1F); // high tag number form not allowed |
michael@0 | 35 | |
michael@0 | 36 | uint8_t tag; |
michael@0 | 37 | if (input.Read(tag) != Success) { |
michael@0 | 38 | return Failure; |
michael@0 | 39 | } |
michael@0 | 40 | |
michael@0 | 41 | if (tag != expectedTag) { |
michael@0 | 42 | return Fail(SEC_ERROR_BAD_DER); |
michael@0 | 43 | } |
michael@0 | 44 | |
michael@0 | 45 | // The short form of length is a single byte with the high order bit set |
michael@0 | 46 | // to zero. The long form of length is one byte with the high order bit |
michael@0 | 47 | // set, followed by N bytes, where N is encoded in the lowest 7 bits of |
michael@0 | 48 | // the first byte. |
michael@0 | 49 | uint8_t length1; |
michael@0 | 50 | if (input.Read(length1) != Success) { |
michael@0 | 51 | return Failure; |
michael@0 | 52 | } |
michael@0 | 53 | if (!(length1 & 0x80)) { |
michael@0 | 54 | length = length1; |
michael@0 | 55 | } else if (length1 == 0x81) { |
michael@0 | 56 | uint8_t length2; |
michael@0 | 57 | if (input.Read(length2) != Success) { |
michael@0 | 58 | return Failure; |
michael@0 | 59 | } |
michael@0 | 60 | if (length2 < 128) { |
michael@0 | 61 | // Not shortest possible encoding |
michael@0 | 62 | return Fail(SEC_ERROR_BAD_DER); |
michael@0 | 63 | } |
michael@0 | 64 | length = length2; |
michael@0 | 65 | } else if (length1 == 0x82) { |
michael@0 | 66 | if (input.Read(length) != Success) { |
michael@0 | 67 | return Failure; |
michael@0 | 68 | } |
michael@0 | 69 | if (length < 256) { |
michael@0 | 70 | // Not shortest possible encoding |
michael@0 | 71 | return Fail(SEC_ERROR_BAD_DER); |
michael@0 | 72 | } |
michael@0 | 73 | } else { |
michael@0 | 74 | // We don't support lengths larger than 2^16 - 1. |
michael@0 | 75 | return Fail(SEC_ERROR_BAD_DER); |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | // Ensure the input is long enough for the length it says it has. |
michael@0 | 79 | return input.EnsureLength(length); |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | } } } // namespace mozilla::pkix::der |