Bug 1083539: Factor out common SEQUENCE unwrapping logic into reusable functions, r=mmc

--HG--
extra : rebase_source : 93d669d3cbe178339fe59c1d9345c773b4e238d4
This commit is contained in:
Brian Smith 2014-10-14 02:07:08 -07:00
parent bda4ef165a
commit 8d32c13ab3
4 changed files with 34 additions and 43 deletions

View File

@ -42,13 +42,8 @@ BackCert::Init()
// The scope of |input| and |certificate| are limited to this block so we
// don't accidentally confuse them for tbsCertificate later.
{
Reader input(der);
Reader certificate;
rv = der::ExpectTagAndGetValue(input, der::SEQUENCE, certificate);
if (rv != Success) {
return rv;
}
rv = der::End(input);
rv = der::ExpectTagAndGetValueAtEnd(der, der::SEQUENCE, certificate);
if (rv != Success) {
return rv;
}

View File

@ -42,7 +42,7 @@
namespace mozilla { namespace pkix { namespace der {
enum Class
enum Class : uint8_t
{
UNIVERSAL = 0 << 6,
// APPLICATION = 1 << 6, // unused
@ -224,6 +224,30 @@ NestedOf(Reader& input, uint8_t outerTag, uint8_t innerTag,
return Success;
}
// Often, a function will need to decode an Input or Reader that contains
// DER-encoded data wrapped in a SEQUENCE (or similar) with nothing after it.
// This function reduces the boilerplate necessary for stripping the outermost
// SEQUENCE (or similar) and ensuring that nothing follows it.
inline Result
ExpectTagAndGetValueAtEnd(Reader& outer, uint8_t expectedTag,
/*out*/ Reader& inner)
{
Result rv = der::ExpectTagAndGetValue(outer, expectedTag, inner);
if (rv != Success) {
return rv;
}
return der::End(outer);
}
// Similar to the above, but takes an Input instead of a Reader&.
inline Result
ExpectTagAndGetValueAtEnd(Input outer, uint8_t expectedTag,
/*out*/ Reader& inner)
{
Reader outerReader(outer);
return ExpectTagAndGetValueAtEnd(outerReader, expectedTag, inner);
}
// Universal types
namespace internal {

View File

@ -174,17 +174,10 @@ SearchForName(/*optional*/ const Input* subjectAltName,
if (subjectAltName) {
Reader altNames;
{
Reader input(*subjectAltName);
rv = der::ExpectTagAndGetValue(input, der::SEQUENCE, altNames);
if (rv != Success) {
return rv;
}
rv = der::End(input);
if (rv != Success) {
return rv;
}
rv = der::ExpectTagAndGetValueAtEnd(*subjectAltName, der::SEQUENCE,
altNames);
if (rv != Success) {
return rv;
}
// do { ... } while(...) because subjectAltName isn't allowed to be empty.

View File

@ -409,23 +409,15 @@ BasicResponse(Reader& input, Context& context)
// [0] wrapper
Reader wrapped;
rv = der::ExpectTagAndGetValue(
rv = der::ExpectTagAndGetValueAtEnd(
input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0, wrapped);
if (rv != Success) {
return rv;
}
rv = der::End(input);
if (rv != Success) {
return rv;
}
// SEQUENCE wrapper
Reader certsSequence;
rv = der::ExpectTagAndGetValue(wrapped, der::SEQUENCE, certsSequence);
if (rv != Success) {
return rv;
}
rv = der::End(wrapped);
rv = der::ExpectTagAndGetValueAtEnd(wrapped, der::SEQUENCE, certsSequence);
if (rv != Success) {
return rv;
}
@ -787,21 +779,8 @@ KeyHash(TrustDomain& trustDomain, const Input subjectPublicKeyInfo,
// subjectPublicKey BIT STRING }
Reader spki;
Result rv;
{
// The scope of input is limited to reduce the possibility of confusing it
// with spki in places we need to be using spki below.
Reader input(subjectPublicKeyInfo);
rv = der::ExpectTagAndGetValue(input, der::SEQUENCE, spki);
if (rv != Success) {
return rv;
}
rv = der::End(input);
if (rv != Success) {
return rv;
}
}
Result rv = der::ExpectTagAndGetValueAtEnd(subjectPublicKeyInfo,
der::SEQUENCE, spki);
// Skip AlgorithmIdentifier
rv = der::ExpectTagAndSkipValue(spki, der::SEQUENCE);