/src/mozilla-central/security/pkix/lib/pkixder.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This code is made available to you under your choice of the following sets |
4 | | * of licensing terms: |
5 | | */ |
6 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
7 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
8 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
9 | | */ |
10 | | /* Copyright 2013 Mozilla Contributors |
11 | | * |
12 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
13 | | * you may not use this file except in compliance with the License. |
14 | | * You may obtain a copy of the License at |
15 | | * |
16 | | * http://www.apache.org/licenses/LICENSE-2.0 |
17 | | * |
18 | | * Unless required by applicable law or agreed to in writing, software |
19 | | * distributed under the License is distributed on an "AS IS" BASIS, |
20 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
21 | | * See the License for the specific language governing permissions and |
22 | | * limitations under the License. |
23 | | */ |
24 | | |
25 | | #ifndef mozilla_pkix_pkixder_h |
26 | | #define mozilla_pkix_pkixder_h |
27 | | |
28 | | // Expect* functions advance the input mark and return Success if the input |
29 | | // matches the given criteria; they fail with the input mark in an undefined |
30 | | // state if the input does not match the criteria. |
31 | | // |
32 | | // Match* functions advance the input mark and return true if the input matches |
33 | | // the given criteria; they return false without changing the input mark if the |
34 | | // input does not match the criteria. |
35 | | // |
36 | | // Skip* functions unconditionally advance the input mark and return Success if |
37 | | // they are able to do so; otherwise they fail with the input mark in an |
38 | | // undefined state. |
39 | | |
40 | | #include "pkix/Input.h" |
41 | | #include "pkix/pkixtypes.h" |
42 | | |
43 | | namespace mozilla { namespace pkix { namespace der { |
44 | | |
45 | | enum Class : uint8_t |
46 | | { |
47 | | UNIVERSAL = 0 << 6, |
48 | | // APPLICATION = 1 << 6, // unused |
49 | | CONTEXT_SPECIFIC = 2 << 6, |
50 | | // PRIVATE = 3 << 6 // unused |
51 | | }; |
52 | | |
53 | | enum Constructed |
54 | | { |
55 | | CONSTRUCTED = 1 << 5 |
56 | | }; |
57 | | |
58 | | enum Tag : uint8_t |
59 | | { |
60 | | BOOLEAN = UNIVERSAL | 0x01, |
61 | | INTEGER = UNIVERSAL | 0x02, |
62 | | BIT_STRING = UNIVERSAL | 0x03, |
63 | | OCTET_STRING = UNIVERSAL | 0x04, |
64 | | NULLTag = UNIVERSAL | 0x05, |
65 | | OIDTag = UNIVERSAL | 0x06, |
66 | | ENUMERATED = UNIVERSAL | 0x0a, |
67 | | UTF8String = UNIVERSAL | 0x0c, |
68 | | SEQUENCE = UNIVERSAL | CONSTRUCTED | 0x10, // 0x30 |
69 | | SET = UNIVERSAL | CONSTRUCTED | 0x11, // 0x31 |
70 | | PrintableString = UNIVERSAL | 0x13, |
71 | | TeletexString = UNIVERSAL | 0x14, |
72 | | IA5String = UNIVERSAL | 0x16, |
73 | | UTCTime = UNIVERSAL | 0x17, |
74 | | GENERALIZED_TIME = UNIVERSAL | 0x18, |
75 | | }; |
76 | | |
77 | | enum class EmptyAllowed { No = 0, Yes = 1 }; |
78 | | |
79 | | Result ReadTagAndGetValue(Reader& input, /*out*/ uint8_t& tag, |
80 | | /*out*/ Input& value); |
81 | | Result End(Reader& input); |
82 | | |
83 | | inline Result |
84 | | ExpectTagAndGetValue(Reader& input, uint8_t tag, /*out*/ Input& value) |
85 | 0 | { |
86 | 0 | uint8_t actualTag; |
87 | 0 | Result rv = ReadTagAndGetValue(input, actualTag, value); |
88 | 0 | if (rv != Success) { |
89 | 0 | return rv; |
90 | 0 | } |
91 | 0 | if (tag != actualTag) { |
92 | 0 | return Result::ERROR_BAD_DER; |
93 | 0 | } |
94 | 0 | return Success; |
95 | 0 | } |
96 | | |
97 | | inline Result |
98 | | ExpectTagAndGetValue(Reader& input, uint8_t tag, /*out*/ Reader& value) |
99 | 0 | { |
100 | 0 | Input valueInput; |
101 | 0 | Result rv = ExpectTagAndGetValue(input, tag, valueInput); |
102 | 0 | if (rv != Success) { |
103 | 0 | return rv; |
104 | 0 | } |
105 | 0 | return value.Init(valueInput); |
106 | 0 | } |
107 | | |
108 | | inline Result |
109 | | ExpectTagAndEmptyValue(Reader& input, uint8_t tag) |
110 | 0 | { |
111 | 0 | Reader value; |
112 | 0 | Result rv = ExpectTagAndGetValue(input, tag, value); |
113 | 0 | if (rv != Success) { |
114 | 0 | return rv; |
115 | 0 | } |
116 | 0 | return End(value); |
117 | 0 | } |
118 | | |
119 | | inline Result |
120 | | ExpectTagAndSkipValue(Reader& input, uint8_t tag) |
121 | 0 | { |
122 | 0 | Input ignoredValue; |
123 | 0 | return ExpectTagAndGetValue(input, tag, ignoredValue); |
124 | 0 | } |
125 | | |
126 | | // Like ExpectTagAndGetValue, except the output Input will contain the |
127 | | // encoded tag and length along with the value. |
128 | | inline Result |
129 | | ExpectTagAndGetTLV(Reader& input, uint8_t tag, /*out*/ Input& tlv) |
130 | 0 | { |
131 | 0 | Reader::Mark mark(input.GetMark()); |
132 | 0 | Result rv = ExpectTagAndSkipValue(input, tag); |
133 | 0 | if (rv != Success) { |
134 | 0 | return rv; |
135 | 0 | } |
136 | 0 | return input.GetInput(mark, tlv); |
137 | 0 | } |
138 | | |
139 | | inline Result |
140 | | End(Reader& input) |
141 | 0 | { |
142 | 0 | if (!input.AtEnd()) { |
143 | 0 | return Result::ERROR_BAD_DER; |
144 | 0 | } |
145 | 0 | |
146 | 0 | return Success; |
147 | 0 | } |
148 | | |
149 | | template <typename Decoder> |
150 | | inline Result |
151 | | Nested(Reader& input, uint8_t tag, Decoder decoder) |
152 | 0 | { |
153 | 0 | Reader nested; |
154 | 0 | Result rv = ExpectTagAndGetValue(input, tag, nested); |
155 | 0 | if (rv != Success) { |
156 | 0 | return rv; |
157 | 0 | } |
158 | 0 | rv = decoder(nested); |
159 | 0 | if (rv != Success) { |
160 | 0 | return rv; |
161 | 0 | } |
162 | 0 | return End(nested); |
163 | 0 | } Unexecuted instantiation: pkixcert.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixcert.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixcheck.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::CheckSubjectPublicKeyInfoContents(mozilla::pkix::Reader&, mozilla::pkix::TrustDomain&, mozilla::pkix::EndEntityOrCA)::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::CheckSubjectPublicKeyInfoContents(mozilla::pkix::Reader&, mozilla::pkix::TrustDomain&, mozilla::pkix::EndEntityOrCA)::$_0) Unexecuted instantiation: pkixcheck.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::CheckSubjectPublicKeyInfo(mozilla::pkix::Input, mozilla::pkix::TrustDomain&, mozilla::pkix::EndEntityOrCA)::$_1>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::CheckSubjectPublicKeyInfo(mozilla::pkix::Input, mozilla::pkix::TrustDomain&, mozilla::pkix::EndEntityOrCA)::$_1) Unexecuted instantiation: pkixcheck.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::CheckBasicConstraints(mozilla::pkix::EndEntityOrCA, mozilla::pkix::Input const*, mozilla::pkix::der::Version, mozilla::pkix::TrustLevel, unsigned int)::$_2>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::CheckBasicConstraints(mozilla::pkix::EndEntityOrCA, mozilla::pkix::Input const*, mozilla::pkix::der::Version, mozilla::pkix::TrustLevel, unsigned int)::$_2) Unexecuted instantiation: pkixcheck.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::CheckExtendedKeyUsage(mozilla::pkix::EndEntityOrCA, mozilla::pkix::Input const*, mozilla::pkix::KeyPurposeId, mozilla::pkix::TrustDomain&, mozilla::pkix::Time)::$_3>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::CheckExtendedKeyUsage(mozilla::pkix::EndEntityOrCA, mozilla::pkix::Input const*, mozilla::pkix::KeyPurposeId, mozilla::pkix::TrustDomain&, mozilla::pkix::Time)::$_3) Unexecuted instantiation: pkixcheck.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::TLSFeaturesSatisfiedInternal(mozilla::pkix::Input const*, mozilla::pkix::Input const*)::$_4>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::TLSFeaturesSatisfiedInternal(mozilla::pkix::Input const*, mozilla::pkix::Input const*)::$_4) Unexecuted instantiation: pkixder.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::der::DigestAlgorithmIdentifier(mozilla::pkix::Reader&, mozilla::pkix::DigestAlgorithm&)::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::der::DigestAlgorithmIdentifier(mozilla::pkix::Reader&, mozilla::pkix::DigestAlgorithm&)::$_0) Unexecuted instantiation: pkixder.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::der::OptionalVersion(mozilla::pkix::Reader&, mozilla::pkix::der::Version&)::$_1>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::der::OptionalVersion(mozilla::pkix::Reader&, mozilla::pkix::der::Version&)::$_1) Unexecuted instantiation: pkixnames.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::(anonymous namespace)::ReadAVA(mozilla::pkix::Reader&, mozilla::pkix::Input&, unsigned char&, mozilla::pkix::Input&)::$_1>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::(anonymous namespace)::ReadAVA(mozilla::pkix::Reader&, mozilla::pkix::Input&, unsigned char&, mozilla::pkix::Input&)::$_1) Unexecuted instantiation: pkixnames.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::(anonymous namespace)::SearchNames(mozilla::pkix::Input const*, mozilla::pkix::Input, mozilla::pkix::(anonymous namespace)::GeneralNameType, mozilla::pkix::Input, mozilla::pkix::FallBackToSearchWithinSubject, mozilla::pkix::(anonymous namespace)::MatchResult&)::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::(anonymous namespace)::SearchNames(mozilla::pkix::Input const*, mozilla::pkix::Input, mozilla::pkix::(anonymous namespace)::GeneralNameType, mozilla::pkix::Input, mozilla::pkix::FallBackToSearchWithinSubject, mozilla::pkix::(anonymous namespace)::MatchResult&)::$_0) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::VerifyEncodedOCSPResponse(mozilla::pkix::TrustDomain&, mozilla::pkix::CertID const&, mozilla::pkix::Time, unsigned short, mozilla::pkix::Input, bool&, mozilla::pkix::Time*, mozilla::pkix::Time*)::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::VerifyEncodedOCSPResponse(mozilla::pkix::TrustDomain&, mozilla::pkix::CertID const&, mozilla::pkix::Time, unsigned short, mozilla::pkix::Input, bool&, mozilla::pkix::Time*, mozilla::pkix::Time*)::$_0) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::OCSPResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::OCSPResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::ResponseBytes(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::ResponseBytes(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::BasicResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BasicResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::ResponseData(mozilla::pkix::Reader&, mozilla::pkix::Context&, mozilla::pkix::der::SignedDataWithSignature const&, mozilla::pkix::DERArray const&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::ResponseData(mozilla::pkix::Reader&, mozilla::pkix::Context&, mozilla::pkix::der::SignedDataWithSignature const&, mozilla::pkix::DERArray const&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#2}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#2}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1} mozilla::pkix::der::Nested<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1})::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1} mozilla::pkix::der::Nested<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1})::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result) Unexecuted instantiation: mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixder_input_tests.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<(anonymous namespace)::pkixder_input_tests_NestedOf_Test::TestBody()::$_0>(mozilla::pkix::Reader&, unsigned char, (anonymous namespace)::pkixder_input_tests_NestedOf_Test::TestBody()::$_0) Unexecuted instantiation: pkixder_input_tests.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<(anonymous namespace)::pkixder_input_tests_NestedOfWithTruncatedData_Test::TestBody()::$_1>(mozilla::pkix::Reader&, unsigned char, (anonymous namespace)::pkixder_input_tests_NestedOfWithTruncatedData_Test::TestBody()::$_1) |
164 | | |
165 | | template <typename Decoder> |
166 | | inline Result |
167 | | Nested(Reader& input, uint8_t outerTag, uint8_t innerTag, Decoder decoder) |
168 | 0 | { |
169 | 0 | Reader nestedInput; |
170 | 0 | Result rv = ExpectTagAndGetValue(input, outerTag, nestedInput); |
171 | 0 | if (rv != Success) { |
172 | 0 | return rv; |
173 | 0 | } |
174 | 0 | rv = Nested(nestedInput, innerTag, decoder); |
175 | 0 | if (rv != Success) { |
176 | 0 | return rv; |
177 | 0 | } |
178 | 0 | return End(nestedInput); |
179 | 0 | } Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::OCSPResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::OCSPResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::ResponseBytes(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::ResponseBytes(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::Nested<mozilla::pkix::BasicResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::BasicResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&)#1}) |
180 | | |
181 | | // This can be used to decode constructs like this: |
182 | | // |
183 | | // ... |
184 | | // foos SEQUENCE OF Foo, |
185 | | // ... |
186 | | // Foo ::= SEQUENCE { |
187 | | // } |
188 | | // |
189 | | // using code like this: |
190 | | // |
191 | | // Result Foo(Reader& r) { /*...*/ } |
192 | | // |
193 | | // rv = der::NestedOf(input, der::SEQEUENCE, der::SEQUENCE, Foo); |
194 | | // |
195 | | // or: |
196 | | // |
197 | | // Result Bar(Reader& r, int value) { /*...*/ } |
198 | | // |
199 | | // int value = /*...*/; |
200 | | // |
201 | | // rv = der::NestedOf(input, der::SEQUENCE, [value](Reader& r) { |
202 | | // return Bar(r, value); |
203 | | // }); |
204 | | // |
205 | | // In these examples the function will get called once for each element of |
206 | | // foos. |
207 | | // |
208 | | template <typename Decoder> |
209 | | inline Result |
210 | | NestedOf(Reader& input, uint8_t outerTag, uint8_t innerTag, |
211 | | EmptyAllowed mayBeEmpty, Decoder decoder) |
212 | 0 | { |
213 | 0 | Reader inner; |
214 | 0 | Result rv = ExpectTagAndGetValue(input, outerTag, inner); |
215 | 0 | if (rv != Success) { |
216 | 0 | return rv; |
217 | 0 | } |
218 | 0 | |
219 | 0 | if (inner.AtEnd()) { |
220 | 0 | if (mayBeEmpty != EmptyAllowed::Yes) { |
221 | 0 | return Result::ERROR_BAD_DER; |
222 | 0 | } |
223 | 0 | return Success; |
224 | 0 | } |
225 | 0 | |
226 | 0 | do { |
227 | 0 | rv = Nested(inner, innerTag, decoder); |
228 | 0 | if (rv != Success) { |
229 | 0 | return rv; |
230 | 0 | } |
231 | 0 | } while (!inner.AtEnd()); |
232 | 0 |
|
233 | 0 | return Success; |
234 | 0 | } Unexecuted instantiation: pkixcert.cpp:mozilla::pkix::Result mozilla::pkix::der::NestedOf<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixcheck.cpp:mozilla::pkix::Result mozilla::pkix::der::NestedOf<mozilla::pkix::CheckExtendedKeyUsage(mozilla::pkix::EndEntityOrCA, mozilla::pkix::Input const*, mozilla::pkix::KeyPurposeId, mozilla::pkix::TrustDomain&, mozilla::pkix::Time)::$_3>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, mozilla::pkix::CheckExtendedKeyUsage(mozilla::pkix::EndEntityOrCA, mozilla::pkix::Input const*, mozilla::pkix::KeyPurposeId, mozilla::pkix::TrustDomain&, mozilla::pkix::Time)::$_3) Unexecuted instantiation: pkixcheck.cpp:mozilla::pkix::Result mozilla::pkix::der::NestedOf<mozilla::pkix::TLSFeaturesSatisfiedInternal(mozilla::pkix::Input const*, mozilla::pkix::Input const*)::$_4>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, mozilla::pkix::TLSFeaturesSatisfiedInternal(mozilla::pkix::Input const*, mozilla::pkix::Input const*)::$_4) Unexecuted instantiation: pkixnames.cpp:mozilla::pkix::Result mozilla::pkix::der::NestedOf<mozilla::pkix::(anonymous namespace)::SearchNames(mozilla::pkix::Input const*, mozilla::pkix::Input, mozilla::pkix::(anonymous namespace)::GeneralNameType, mozilla::pkix::Input, mozilla::pkix::FallBackToSearchWithinSubject, mozilla::pkix::(anonymous namespace)::MatchResult&)::$_0>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, mozilla::pkix::(anonymous namespace)::SearchNames(mozilla::pkix::Input const*, mozilla::pkix::Input, mozilla::pkix::(anonymous namespace)::GeneralNameType, mozilla::pkix::Input, mozilla::pkix::FallBackToSearchWithinSubject, mozilla::pkix::(anonymous namespace)::MatchResult&)::$_0) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::NestedOf<mozilla::pkix::ResponseData(mozilla::pkix::Reader&, mozilla::pkix::Context&, mozilla::pkix::der::SignedDataWithSignature const&, mozilla::pkix::DERArray const&)::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, mozilla::pkix::ResponseData(mozilla::pkix::Reader&, mozilla::pkix::Context&, mozilla::pkix::der::SignedDataWithSignature const&, mozilla::pkix::DERArray const&)::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1} mozilla::pkix::der::NestedOf<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1})::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, mozilla::pkix::Result) Unexecuted instantiation: mozilla::pkix::Result mozilla::pkix::der::NestedOf<mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}) Unexecuted instantiation: pkixder_input_tests.cpp:mozilla::pkix::Result mozilla::pkix::der::NestedOf<(anonymous namespace)::pkixder_input_tests_NestedOf_Test::TestBody()::$_0>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, (anonymous namespace)::pkixder_input_tests_NestedOf_Test::TestBody()::$_0) Unexecuted instantiation: pkixder_input_tests.cpp:mozilla::pkix::Result mozilla::pkix::der::NestedOf<(anonymous namespace)::pkixder_input_tests_NestedOfWithTruncatedData_Test::TestBody()::$_1>(mozilla::pkix::Reader&, unsigned char, unsigned char, mozilla::pkix::der::EmptyAllowed, (anonymous namespace)::pkixder_input_tests_NestedOfWithTruncatedData_Test::TestBody()::$_1) |
235 | | |
236 | | // Often, a function will need to decode an Input or Reader that contains |
237 | | // DER-encoded data wrapped in a SEQUENCE (or similar) with nothing after it. |
238 | | // This function reduces the boilerplate necessary for stripping the outermost |
239 | | // SEQUENCE (or similar) and ensuring that nothing follows it. |
240 | | inline Result |
241 | | ExpectTagAndGetValueAtEnd(Reader& outer, uint8_t expectedTag, |
242 | | /*out*/ Reader& inner) |
243 | 0 | { |
244 | 0 | Result rv = der::ExpectTagAndGetValue(outer, expectedTag, inner); |
245 | 0 | if (rv != Success) { |
246 | 0 | return rv; |
247 | 0 | } |
248 | 0 | return der::End(outer); |
249 | 0 | } |
250 | | |
251 | | // Similar to the above, but takes an Input instead of a Reader&. |
252 | | inline Result |
253 | | ExpectTagAndGetValueAtEnd(Input outer, uint8_t expectedTag, |
254 | | /*out*/ Reader& inner) |
255 | 0 | { |
256 | 0 | Reader outerReader(outer); |
257 | 0 | return ExpectTagAndGetValueAtEnd(outerReader, expectedTag, inner); |
258 | 0 | } |
259 | | |
260 | | // Universal types |
261 | | |
262 | | namespace internal { |
263 | | |
264 | | enum class IntegralValueRestriction |
265 | | { |
266 | | NoRestriction, |
267 | | MustBePositive, |
268 | | MustBe0To127, |
269 | | }; |
270 | | |
271 | | Result IntegralBytes(Reader& input, uint8_t tag, |
272 | | IntegralValueRestriction valueRestriction, |
273 | | /*out*/ Input& value, |
274 | | /*optional out*/ Input::size_type* significantBytes = nullptr); |
275 | | |
276 | | // This parser will only parse values between 0..127. If this range is |
277 | | // increased then callers will need to be changed. |
278 | | Result IntegralValue(Reader& input, uint8_t tag, /*out*/ uint8_t& value); |
279 | | |
280 | | } // namespace internal |
281 | | |
282 | | Result |
283 | | BitStringWithNoUnusedBits(Reader& input, /*out*/ Input& value); |
284 | | |
285 | | inline Result |
286 | | Boolean(Reader& input, /*out*/ bool& value) |
287 | 0 | { |
288 | 0 | Reader valueReader; |
289 | 0 | Result rv = ExpectTagAndGetValue(input, BOOLEAN, valueReader); |
290 | 0 | if (rv != Success) { |
291 | 0 | return rv; |
292 | 0 | } |
293 | 0 | |
294 | 0 | uint8_t intValue; |
295 | 0 | rv = valueReader.Read(intValue); |
296 | 0 | if (rv != Success) { |
297 | 0 | return rv; |
298 | 0 | } |
299 | 0 | rv = End(valueReader); |
300 | 0 | if (rv != Success) { |
301 | 0 | return rv; |
302 | 0 | } |
303 | 0 | switch (intValue) { |
304 | 0 | case 0: value = false; return Success; |
305 | 0 | case 0xFF: value = true; return Success; |
306 | 0 | default: |
307 | 0 | return Result::ERROR_BAD_DER; |
308 | 0 | } |
309 | 0 | } |
310 | | |
311 | | // This is for BOOLEAN DEFAULT FALSE. |
312 | | // The standard stipulates that "The encoding of a set value or sequence value |
313 | | // shall not include an encoding for any component value which is equal to its |
314 | | // default value." However, it appears to be common that other libraries |
315 | | // incorrectly include the value of a BOOLEAN even when it's equal to the |
316 | | // default value, so we allow invalid explicit encodings here. |
317 | | inline Result |
318 | | OptionalBoolean(Reader& input, /*out*/ bool& value) |
319 | 0 | { |
320 | 0 | value = false; |
321 | 0 | if (input.Peek(BOOLEAN)) { |
322 | 0 | Result rv = Boolean(input, value); |
323 | 0 | if (rv != Success) { |
324 | 0 | return rv; |
325 | 0 | } |
326 | 0 | } |
327 | 0 | return Success; |
328 | 0 | } |
329 | | |
330 | | // This parser will only parse values between 0..127. If this range is |
331 | | // increased then callers will need to be changed. |
332 | | inline Result |
333 | | Enumerated(Reader& input, uint8_t& value) |
334 | 0 | { |
335 | 0 | return internal::IntegralValue(input, ENUMERATED | 0, value); |
336 | 0 | } |
337 | | |
338 | | namespace internal { |
339 | | |
340 | | // internal::TimeChoice implements the shared functionality of GeneralizedTime |
341 | | // and TimeChoice. tag must be either UTCTime or GENERALIZED_TIME. |
342 | | // |
343 | | // Only times from 1970-01-01-00:00:00 onward are accepted, in order to |
344 | | // eliminate the chance for complications in converting times to traditional |
345 | | // time formats that start at 1970. |
346 | | Result TimeChoice(Reader& input, uint8_t tag, /*out*/ Time& time); |
347 | | |
348 | | } // namespace internal |
349 | | |
350 | | // Only times from 1970-01-01-00:00:00 onward are accepted, in order to |
351 | | // eliminate the chance for complications in converting times to traditional |
352 | | // time formats that start at 1970. |
353 | | inline Result |
354 | | GeneralizedTime(Reader& input, /*out*/ Time& time) |
355 | 0 | { |
356 | 0 | return internal::TimeChoice(input, GENERALIZED_TIME, time); |
357 | 0 | } |
358 | | |
359 | | // Only times from 1970-01-01-00:00:00 onward are accepted, in order to |
360 | | // eliminate the chance for complications in converting times to traditional |
361 | | // time formats that start at 1970. |
362 | | inline Result |
363 | | TimeChoice(Reader& input, /*out*/ Time& time) |
364 | 0 | { |
365 | 0 | uint8_t expectedTag = input.Peek(UTCTime) ? UTCTime : GENERALIZED_TIME; |
366 | 0 | return internal::TimeChoice(input, expectedTag, time); |
367 | 0 | } |
368 | | |
369 | | // Parse a DER integer value into value. Empty values, negative values, and |
370 | | // zero are rejected. If significantBytes is not null, then it will be set to |
371 | | // the number of significant bytes in the value (the length of the value, less |
372 | | // the length of any leading padding), which is useful for key size checks. |
373 | | inline Result |
374 | | PositiveInteger(Reader& input, /*out*/ Input& value, |
375 | | /*optional out*/ Input::size_type* significantBytes = nullptr) |
376 | 0 | { |
377 | 0 | return internal::IntegralBytes( |
378 | 0 | input, INTEGER, internal::IntegralValueRestriction::MustBePositive, |
379 | 0 | value, significantBytes); |
380 | 0 | } |
381 | | |
382 | | // This parser will only parse values between 0..127. If this range is |
383 | | // increased then callers will need to be changed. |
384 | | inline Result |
385 | | Integer(Reader& input, /*out*/ uint8_t& value) |
386 | 0 | { |
387 | 0 | return internal::IntegralValue(input, INTEGER, value); |
388 | 0 | } |
389 | | |
390 | | // This parser will only parse values between 0..127. If this range is |
391 | | // increased then callers will need to be changed. The default value must be |
392 | | // -1; defaultValue is only a parameter to make it clear in the calling code |
393 | | // what the default value is. |
394 | | inline Result |
395 | | OptionalInteger(Reader& input, long defaultValue, /*out*/ long& value) |
396 | 0 | { |
397 | 0 | // If we need to support a different default value in the future, we need to |
398 | 0 | // test that parsedValue != defaultValue. |
399 | 0 | if (defaultValue != -1) { |
400 | 0 | return Result::FATAL_ERROR_INVALID_ARGS; |
401 | 0 | } |
402 | 0 | |
403 | 0 | if (!input.Peek(INTEGER)) { |
404 | 0 | value = defaultValue; |
405 | 0 | return Success; |
406 | 0 | } |
407 | 0 | |
408 | 0 | uint8_t parsedValue; |
409 | 0 | Result rv = Integer(input, parsedValue); |
410 | 0 | if (rv != Success) { |
411 | 0 | return rv; |
412 | 0 | } |
413 | 0 | value = parsedValue; |
414 | 0 | return Success; |
415 | 0 | } |
416 | | |
417 | | inline Result |
418 | | Null(Reader& input) |
419 | 0 | { |
420 | 0 | return ExpectTagAndEmptyValue(input, NULLTag); |
421 | 0 | } |
422 | | |
423 | | template <uint8_t Len> |
424 | | Result |
425 | | OID(Reader& input, const uint8_t (&expectedOid)[Len]) |
426 | 0 | { |
427 | 0 | Reader value; |
428 | 0 | Result rv = ExpectTagAndGetValue(input, OIDTag, value); |
429 | 0 | if (rv != Success) { |
430 | 0 | return rv; |
431 | 0 | } |
432 | 0 | if (!value.MatchRest(expectedOid)) { |
433 | 0 | return Result::ERROR_BAD_DER; |
434 | 0 | } |
435 | 0 | return Success; |
436 | 0 | } |
437 | | |
438 | | // PKI-specific types |
439 | | |
440 | | inline Result |
441 | | CertificateSerialNumber(Reader& input, /*out*/ Input& value) |
442 | 0 | { |
443 | 0 | // http://tools.ietf.org/html/rfc5280#section-4.1.2.2: |
444 | 0 | // |
445 | 0 | // * "The serial number MUST be a positive integer assigned by the CA to |
446 | 0 | // each certificate." |
447 | 0 | // * "Certificate users MUST be able to handle serialNumber values up to 20 |
448 | 0 | // octets. Conforming CAs MUST NOT use serialNumber values longer than 20 |
449 | 0 | // octets." |
450 | 0 | // * "Note: Non-conforming CAs may issue certificates with serial numbers |
451 | 0 | // that are negative or zero. Certificate users SHOULD be prepared to |
452 | 0 | // gracefully handle such certificates." |
453 | 0 | return internal::IntegralBytes( |
454 | 0 | input, INTEGER, internal::IntegralValueRestriction::NoRestriction, |
455 | 0 | value); |
456 | 0 | } |
457 | | |
458 | | // x.509 and OCSP both use this same version numbering scheme, though OCSP |
459 | | // only supports v1. |
460 | | enum class Version { v1 = 0, v2 = 1, v3 = 2, v4 = 3, Uninitialized = 255 }; |
461 | | |
462 | | // X.509 Certificate and OCSP ResponseData both use |
463 | | // "[0] EXPLICIT Version DEFAULT v1". Although an explicit encoding of v1 is |
464 | | // illegal, we support it because some real-world OCSP responses explicitly |
465 | | // encode it. |
466 | | Result OptionalVersion(Reader& input, /*out*/ Version& version); |
467 | | |
468 | | template <typename ExtensionHandler> |
469 | | inline Result |
470 | | OptionalExtensions(Reader& input, uint8_t tag, |
471 | | ExtensionHandler extensionHandler) |
472 | 0 | { |
473 | 0 | if (!input.Peek(tag)) { |
474 | 0 | return Success; |
475 | 0 | } |
476 | 0 | |
477 | 0 | return Nested(input, tag, [extensionHandler](Reader& tagged) { |
478 | 0 | // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension |
479 | 0 | // |
480 | 0 | // TODO(bug 997994): According to the specification, there should never be |
481 | 0 | // an empty sequence of extensions but we've found OCSP responses that have |
482 | 0 | // that (see bug 991898). |
483 | 0 | return NestedOf(tagged, SEQUENCE, SEQUENCE, EmptyAllowed::Yes, |
484 | 0 | [extensionHandler](Reader& extension) -> Result { |
485 | 0 | // Extension ::= SEQUENCE { |
486 | 0 | // extnID OBJECT IDENTIFIER, |
487 | 0 | // critical BOOLEAN DEFAULT FALSE, |
488 | 0 | // extnValue OCTET STRING |
489 | 0 | // } |
490 | 0 | Reader extnID; |
491 | 0 | Result rv = ExpectTagAndGetValue(extension, OIDTag, extnID); |
492 | 0 | if (rv != Success) { |
493 | 0 | return rv; |
494 | 0 | } |
495 | 0 | bool critical; |
496 | 0 | rv = OptionalBoolean(extension, critical); |
497 | 0 | if (rv != Success) { |
498 | 0 | return rv; |
499 | 0 | } |
500 | 0 | Input extnValue; |
501 | 0 | rv = ExpectTagAndGetValue(extension, OCTET_STRING, extnValue); |
502 | 0 | if (rv != Success) { |
503 | 0 | return rv; |
504 | 0 | } |
505 | 0 | bool understood = false; |
506 | 0 | rv = extensionHandler(extnID, extnValue, critical, understood); |
507 | 0 | if (rv != Success) { |
508 | 0 | return rv; |
509 | 0 | } |
510 | 0 | if (critical && !understood) { |
511 | 0 | return Result::ERROR_UNKNOWN_CRITICAL_EXTENSION; |
512 | 0 | } |
513 | 0 | return Success; |
514 | 0 | }); Unexecuted instantiation: pkixcert.cpp:mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1})::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const Unexecuted instantiation: mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const |
515 | 0 | }); Unexecuted instantiation: pkixcert.cpp:mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0)::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1})::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const Unexecuted instantiation: mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&))::{lambda(mozilla::pkix::Reader&)#1}::operator()(mozilla::pkix::Reader&) const |
516 | 0 | } Unexecuted instantiation: pkixcert.cpp:mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::BackCert::Init()::$_0>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::BackCert::Init()::$_0) Unexecuted instantiation: pkixocsp.cpp:mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1}>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::SingleResponse(mozilla::pkix::Reader&, mozilla::pkix::Context&)::{lambda(mozilla::pkix::Reader&, mozilla::pkix::Input const&, bool, bool&)#1}) Unexecuted instantiation: mozilla::pkix::Result mozilla::pkix::der::OptionalExtensions<mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)>(mozilla::pkix::Reader&, unsigned char, mozilla::pkix::Result (*)(mozilla::pkix::Reader&, mozilla::pkix::Input, bool, bool&)) |
517 | | |
518 | | Result DigestAlgorithmIdentifier(Reader& input, |
519 | | /*out*/ DigestAlgorithm& algorithm); |
520 | | |
521 | | enum class PublicKeyAlgorithm |
522 | | { |
523 | | RSA_PKCS1, |
524 | | ECDSA, |
525 | | Uninitialized |
526 | | }; |
527 | | |
528 | | Result SignatureAlgorithmIdentifierValue( |
529 | | Reader& input, |
530 | | /*out*/ PublicKeyAlgorithm& publicKeyAlgorithm, |
531 | | /*out*/ DigestAlgorithm& digestAlgorithm); |
532 | | |
533 | | struct SignedDataWithSignature final |
534 | | { |
535 | | public: |
536 | | Input data; |
537 | | Input algorithm; |
538 | | Input signature; |
539 | | |
540 | | void operator=(const SignedDataWithSignature&) = delete; |
541 | | }; |
542 | | |
543 | | // Parses a SEQUENCE into tbs and then parses an AlgorithmIdentifier followed |
544 | | // by a BIT STRING into signedData. This handles the commonality between |
545 | | // parsing the signed/signature fields of certificates and OCSP responses. In |
546 | | // the case of an OCSP response, the caller needs to parse the certs |
547 | | // separately. |
548 | | // |
549 | | // Note that signatureAlgorithm is NOT parsed or validated. |
550 | | // |
551 | | // Certificate ::= SEQUENCE { |
552 | | // tbsCertificate TBSCertificate, |
553 | | // signatureAlgorithm AlgorithmIdentifier, |
554 | | // signatureValue BIT STRING } |
555 | | // |
556 | | // BasicOCSPResponse ::= SEQUENCE { |
557 | | // tbsResponseData ResponseData, |
558 | | // signatureAlgorithm AlgorithmIdentifier, |
559 | | // signature BIT STRING, |
560 | | // certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } |
561 | | Result SignedData(Reader& input, /*out*/ Reader& tbs, |
562 | | /*out*/ SignedDataWithSignature& signedDataWithSignature); |
563 | | |
564 | | } } } // namespace mozilla::pkix::der |
565 | | |
566 | | #endif // mozilla_pkix_pkixder_h |