Bug 1038837: Factor out mozilla::pkix::Input into a separate header, r=mmc

--HG--
rename : security/pkix/lib/pkixder.h => security/pkix/include/pkix/Input.h
rename : security/pkix/lib/pkixutil.h => security/pkix/include/pkix/Result.h
extra : rebase_source : 09bac0a183932f721cdfd32936595867e4dc26ce
This commit is contained in:
Brian Smith 2014-07-13 13:17:36 -07:00
parent 96c220acca
commit 8483b958ad
9 changed files with 310 additions and 267 deletions

View File

@ -0,0 +1,240 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This code is made available to you under your choice of the following sets
* of licensing terms:
*/
/* 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/.
*/
/* Copyright 2013 Mozilla Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef mozilla_pkix__Input_h
#define mozilla_pkix__Input_h
#include "pkix/nullptr.h"
#include "pkix/Result.h"
#include "stdint.h"
namespace mozilla { namespace pkix {
// Expect* functions advance the input mark and return Success if the input
// matches the given criteria; they fail with the input mark in an undefined
// state if the input does not match the criteria.
//
// Match* functions advance the input mark and return true if the input matches
// the given criteria; they return false without changing the input mark if the
// input does not match the criteria.
//
// Skip* functions unconditionally advance the input mark and return Success if
// they are able to do so; otherwise they fail with the input mark in an
// undefined state.
class Input
{
public:
Input()
: input(nullptr)
, end(nullptr)
{
}
Result Init(const uint8_t* data, size_t len)
{
if (input) {
// already initialized
return Fail(SEC_ERROR_INVALID_ARGS);
}
if (!data || len > 0xffffu) {
// input too large
return Fail(SEC_ERROR_BAD_DER);
}
// XXX: this->input = input bug was not caught by tests! Why not?
// this->end = end bug was not caught by tests! Why not?
this->input = data;
this->end = data + len;
return Success;
}
Result Expect(const uint8_t* expected, uint16_t expectedLen)
{
Result rv = EnsureLength(expectedLen);
if (rv != Success) {
return rv;
}
if (memcmp(input, expected, expectedLen)) {
return Fail(SEC_ERROR_BAD_DER);
}
input += expectedLen;
return Success;
}
bool Peek(uint8_t expectedByte) const
{
return input < end && *input == expectedByte;
}
Result Read(uint8_t& out)
{
Result rv = EnsureLength(1);
if (rv != Success) {
return rv;
}
out = *input++;
return Success;
}
Result Read(uint16_t& out)
{
Result rv = EnsureLength(2);
if (rv != Success) {
return rv;
}
out = *input++;
out <<= 8u;
out |= *input++;
return Success;
}
template <uint16_t N>
bool MatchRest(const uint8_t (&toMatch)[N])
{
// Normally we use EnsureLength which compares (input + len < end), but
// here we want to be sure that there is nothing following the matched
// bytes
if (static_cast<size_t>(end - input) != N) {
return false;
}
if (memcmp(input, toMatch, N)) {
return false;
}
input += N;
return true;
}
template <uint16_t N>
bool MatchTLV(uint8_t tag, uint16_t len, const uint8_t (&value)[N])
{
static_assert(N <= 127, "buffer larger than largest length supported");
if (len > N) {
PR_NOT_REACHED("overflow prevented dynamically instead of statically");
return false;
}
uint16_t totalLen = 2u + len;
if (EnsureLength(totalLen) != Success) {
return false;
}
if (*input != tag) {
return false;
}
if (*(input + 1) != len) {
return false;
}
if (memcmp(input + 2, value, len)) {
return false;
}
input += totalLen;
return true;
}
Result Skip(uint16_t len)
{
Result rv = EnsureLength(len);
if (rv != Success) {
return rv;
}
input += len;
return Success;
}
Result Skip(uint16_t len, Input& skippedInput)
{
Result rv = EnsureLength(len);
if (rv != Success) {
return rv;
}
rv = skippedInput.Init(input, len);
if (rv != Success) {
return rv;
}
input += len;
return Success;
}
Result Skip(uint16_t len, SECItem& skippedItem)
{
Result rv = EnsureLength(len);
if (rv != Success) {
return rv;
}
skippedItem.type = siBuffer;
skippedItem.data = const_cast<uint8_t*>(input);
skippedItem.len = len;
input += len;
return Success;
}
void SkipToEnd()
{
input = end;
}
Result EnsureLength(uint16_t len)
{
if (static_cast<size_t>(end - input) < len) {
return Fail(SEC_ERROR_BAD_DER);
}
return Success;
}
bool AtEnd() const { return input == end; }
class Mark
{
private:
friend class Input;
Mark(const Input& input, const uint8_t* mark) : input(input), mark(mark) { }
const Input& input;
const uint8_t* const mark;
void operator=(const Mark&) /* = delete */;
};
Mark GetMark() const { return Mark(*this, input); }
Result GetSECItem(SECItemType type, const Mark& mark, /*out*/ SECItem& item)
{
if (&mark.input != this || mark.mark > input) {
PR_NOT_REACHED("invalid mark");
return Fail(SEC_ERROR_INVALID_ARGS);
}
item.type = type;
item.data = const_cast<uint8_t*>(mark.mark);
item.len = static_cast<decltype(item.len)>(input - mark.mark);
return Success;
}
private:
const uint8_t* input;
const uint8_t* end;
Input(const Input&) /* = delete */;
void operator=(const Input&) /* = delete */;
};
} } // namespace mozilla::pkix
#endif // mozilla_pkix__Input_h

View File

@ -76,6 +76,14 @@ MapSECStatus(SECStatus srv)
return RecoverableError;
}
inline Result
Fail(PRErrorCode errorCode)
{
PR_ASSERT(errorCode != 0);
PR_SetError(errorCode, 0);
return mozilla::pkix::MapSECStatus(SECFailure);
}
} } // namespace mozilla::pkix
#endif // mozilla_pkix__Result_h

View File

@ -37,17 +37,17 @@ BackCert::Init()
// signatureAlgorithm AlgorithmIdentifier,
// signatureValue BIT STRING }
der::Input tbsCertificate;
Input tbsCertificate;
// The scope of |input| and |certificate| are limited to this block so we
// don't accidentally confuse them for tbsCertificate later.
{
der::Input input;
Input input;
rv = input.Init(der.data, der.len);
if (rv != Success) {
return rv;
}
der::Input certificate;
Input certificate;
rv = der::ExpectTagAndGetValue(input, der::SEQUENCE, certificate);
if (rv != Success) {
return rv;
@ -163,7 +163,7 @@ BackCert::Init()
}
Result
BackCert::RememberExtension(der::Input& extnID, const SECItem& extnValue,
BackCert::RememberExtension(Input& extnID, const SECItem& extnValue,
/*out*/ bool& understood)
{
understood = false;
@ -243,11 +243,11 @@ BackCert::RememberExtension(der::Input& extnID, const SECItem& extnValue,
// Don't allow an empty value for any extension we understand. This way, we
// can test out->len to check for duplicates.
if (extnValue.len == 0) {
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
return Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
}
if (out->len != 0) {
// Duplicate extension
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
return Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
}
*out = extnValue;
understood = true;

View File

@ -35,7 +35,7 @@ namespace mozilla { namespace pkix {
Result
CheckValidity(const SECItem& encodedValidity, PRTime time)
{
der::Input validity;
Input validity;
if (validity.Init(encodedValidity.data, encodedValidity.len) != Success) {
return Fail(RecoverableError, SEC_ERROR_EXPIRED_CERTIFICATE);
}
@ -87,11 +87,11 @@ CheckKeyUsage(EndEntityOrCA endEntityOrCA, const SECItem* encodedKeyUsage,
return Success;
}
der::Input input;
Input input;
if (input.Init(encodedKeyUsage->data, encodedKeyUsage->len) != Success) {
return Fail(RecoverableError, SEC_ERROR_INADEQUATE_KEY_USAGE);
}
der::Input value;
Input value;
if (der::ExpectTagAndGetValue(input, der::BIT_STRING, value) != Success) {
return Fail(RecoverableError, SEC_ERROR_INADEQUATE_KEY_USAGE);
}
@ -203,7 +203,7 @@ bool CertPolicyId::IsAnyPolicy() const
// policyQualifiers SEQUENCE SIZE (1..MAX) OF
// PolicyQualifierInfo OPTIONAL }
inline Result
CheckPolicyInformation(der::Input& input, EndEntityOrCA endEntityOrCA,
CheckPolicyInformation(Input& input, EndEntityOrCA endEntityOrCA,
const CertPolicyId& requiredPolicy,
/*in/out*/ bool& found)
{
@ -271,7 +271,7 @@ CheckCertificatePolicies(EndEntityOrCA endEntityOrCA,
bool found = false;
der::Input input;
Input input;
if (input.Init(encodedCertificatePolicies->data,
encodedCertificatePolicies->len) != Success) {
return Fail(RecoverableError, SEC_ERROR_POLICY_VALIDATION_FAILED);
@ -297,7 +297,7 @@ static const long UNLIMITED_PATH_LEN = -1; // must be less than zero
// cA BOOLEAN DEFAULT FALSE,
// pathLenConstraint INTEGER (0..MAX) OPTIONAL }
static Result
DecodeBasicConstraints(der::Input& input, /*out*/ bool& isCA,
DecodeBasicConstraints(Input& input, /*out*/ bool& isCA,
/*out*/ long& pathLenConstraint)
{
// TODO(bug 989518): cA is by default false. According to DER, default
@ -307,15 +307,15 @@ DecodeBasicConstraints(der::Input& input, /*out*/ bool& isCA,
// enforce this yet (hence passing true for allowInvalidExplicitEncoding
// to der::OptionalBoolean).
if (der::OptionalBoolean(input, true, isCA) != Success) {
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
return Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
}
// TODO(bug 985025): If isCA is false, pathLenConstraint MUST NOT
// be included (as per RFC 5280 section 4.2.1.9), but for compatibility
// reasons, we don't check this for now.
if (OptionalInteger(input, UNLIMITED_PATH_LEN, pathLenConstraint)
if (der::OptionalInteger(input, UNLIMITED_PATH_LEN, pathLenConstraint)
!= Success) {
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
return Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
}
return Success;
@ -332,7 +332,7 @@ CheckBasicConstraints(EndEntityOrCA endEntityOrCA,
long pathLenConstraint = UNLIMITED_PATH_LEN;
if (encodedBasicConstraints) {
der::Input input;
Input input;
if (input.Init(encodedBasicConstraints->data,
encodedBasicConstraints->len) != Success) {
return Fail(RecoverableError, SEC_ERROR_EXTENSION_VALUE_INVALID);
@ -462,7 +462,7 @@ CheckNameConstraints(const SECItem& encodedNameConstraints,
// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
static Result
MatchEKU(der::Input& value, KeyPurposeId requiredEKU,
MatchEKU(Input& value, KeyPurposeId requiredEKU,
EndEntityOrCA endEntityOrCA, /*in/out*/ bool& found,
/*in/out*/ bool& foundOCSPSigning)
{
@ -522,11 +522,11 @@ MatchEKU(der::Input& value, KeyPurposeId requiredEKU,
case KeyPurposeId::anyExtendedKeyUsage:
PR_NOT_REACHED("anyExtendedKeyUsage should start with found==true");
return der::Fail(SEC_ERROR_LIBRARY_FAILURE);
return Fail(SEC_ERROR_LIBRARY_FAILURE);
default:
PR_NOT_REACHED("unrecognized EKU");
return der::Fail(SEC_ERROR_LIBRARY_FAILURE);
return Fail(SEC_ERROR_LIBRARY_FAILURE);
}
}
@ -559,7 +559,7 @@ CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA,
if (encodedExtendedKeyUsage) {
bool found = requiredEKU == KeyPurposeId::anyExtendedKeyUsage;
der::Input input;
Input input;
if (input.Init(encodedExtendedKeyUsage->data,
encodedExtendedKeyUsage->len) != Success) {
return Fail(RecoverableError, SEC_ERROR_INADEQUATE_CERT_TYPE);

View File

@ -28,14 +28,6 @@
namespace mozilla { namespace pkix { namespace der {
// not inline
Result
Fail(PRErrorCode errorCode)
{
PR_SetError(errorCode, 0);
return MapSECStatus(SECFailure);
}
namespace internal {
// Too complicated to be inline

View File

@ -38,12 +38,10 @@
// undefined state.
#include "pkix/enumclass.h"
#include "pkix/Input.h"
#include "pkix/pkixtypes.h"
#include "pkix/Result.h"
#include "prtime.h"
#include "secerr.h"
#include "secoidt.h"
#include "stdint.h"
typedef struct CERTSignedDataStr CERTSignedData;
@ -78,201 +76,6 @@ enum Tag
MOZILLA_PKIX_ENUM_CLASS EmptyAllowed { No = 0, Yes = 1 };
Result Fail(PRErrorCode errorCode);
class Input
{
public:
Input()
: input(nullptr)
, end(nullptr)
{
}
Result Init(const uint8_t* data, size_t len)
{
if (input) {
// already initialized
return Fail(SEC_ERROR_INVALID_ARGS);
}
if (!data || len > 0xffffu) {
// input too large
return Fail(SEC_ERROR_BAD_DER);
}
// XXX: this->input = input bug was not caught by tests! Why not?
// this->end = end bug was not caught by tests! Why not?
this->input = data;
this->end = data + len;
return Success;
}
Result Expect(const uint8_t* expected, uint16_t expectedLen)
{
Result rv = EnsureLength(expectedLen);
if (rv != Success) {
return rv;
}
if (memcmp(input, expected, expectedLen)) {
return Fail(SEC_ERROR_BAD_DER);
}
input += expectedLen;
return Success;
}
bool Peek(uint8_t expectedByte) const
{
return input < end && *input == expectedByte;
}
Result Read(uint8_t& out)
{
Result rv = EnsureLength(1);
if (rv != Success) {
return rv;
}
out = *input++;
return Success;
}
Result Read(uint16_t& out)
{
Result rv = EnsureLength(2);
if (rv != Success) {
return rv;
}
out = *input++;
out <<= 8u;
out |= *input++;
return Success;
}
template <uint16_t N>
bool MatchRest(const uint8_t (&toMatch)[N])
{
// Normally we use EnsureLength which compares (input + len < end), but
// here we want to be sure that there is nothing following the matched
// bytes
if (static_cast<size_t>(end - input) != N) {
return false;
}
if (memcmp(input, toMatch, N)) {
return false;
}
input += N;
return true;
}
template <uint16_t N>
bool MatchTLV(uint8_t tag, uint16_t len, const uint8_t (&value)[N])
{
static_assert(N <= 127, "buffer larger than largest length supported");
if (len > N) {
PR_NOT_REACHED("overflow prevented dynamically instead of statically");
return false;
}
uint16_t totalLen = 2u + len;
if (EnsureLength(totalLen) != Success) {
return false;
}
if (*input != tag) {
return false;
}
if (*(input + 1) != len) {
return false;
}
if (memcmp(input + 2, value, len)) {
return false;
}
input += totalLen;
return true;
}
Result Skip(uint16_t len)
{
Result rv = EnsureLength(len);
if (rv != Success) {
return rv;
}
input += len;
return Success;
}
Result Skip(uint16_t len, Input& skippedInput)
{
Result rv = EnsureLength(len);
if (rv != Success) {
return rv;
}
rv = skippedInput.Init(input, len);
if (rv != Success) {
return rv;
}
input += len;
return Success;
}
Result Skip(uint16_t len, SECItem& skippedItem)
{
Result rv = EnsureLength(len);
if (rv != Success) {
return rv;
}
skippedItem.type = siBuffer;
skippedItem.data = const_cast<uint8_t*>(input);
skippedItem.len = len;
input += len;
return Success;
}
void SkipToEnd()
{
input = end;
}
Result EnsureLength(uint16_t len)
{
if (static_cast<size_t>(end - input) < len) {
return Fail(SEC_ERROR_BAD_DER);
}
return Success;
}
bool AtEnd() const { return input == end; }
class Mark
{
private:
friend class Input;
Mark(const Input& input, const uint8_t* mark) : input(input), mark(mark) { }
const Input& input;
const uint8_t* const mark;
void operator=(const Mark&) /* = delete */;
};
Mark GetMark() const { return Mark(*this, input); }
Result GetSECItem(SECItemType type, const Mark& mark, /*out*/ SECItem& item)
{
if (&mark.input != this || mark.mark > input) {
PR_NOT_REACHED("invalid mark");
return Fail(SEC_ERROR_INVALID_ARGS);
}
item.type = type;
item.data = const_cast<uint8_t*>(mark.mark);
item.len = static_cast<decltype(item.len)>(input - mark.mark);
return Success;
}
private:
const uint8_t* input;
const uint8_t* end;
Input(const Input&) /* = delete */;
void operator=(const Input&) /* = delete */;
};
inline Result
ExpectTagAndLength(Input& input, uint8_t expectedTag, uint8_t expectedLength)
{

View File

@ -153,19 +153,19 @@ MOZILLA_PKIX_ENUM_CLASS ResponderIDType : uint8_t
byKey = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 2
};
static inline Result OCSPResponse(der::Input&, Context&);
static inline Result ResponseBytes(der::Input&, Context&);
static inline Result BasicResponse(der::Input&, Context&);
static inline Result OCSPResponse(Input&, Context&);
static inline Result ResponseBytes(Input&, Context&);
static inline Result BasicResponse(Input&, Context&);
static inline Result ResponseData(
der::Input& tbsResponseData,
Input& tbsResponseData,
Context& context,
const SignedDataWithSignature& signedResponseData,
/*const*/ SECItem* certs, size_t numCerts);
static inline Result SingleResponse(der::Input& input, Context& context);
static Result ExtensionNotUnderstood(der::Input& extnID,
static inline Result SingleResponse(Input& input, Context& context);
static Result ExtensionNotUnderstood(Input& extnID,
const SECItem& extnValue,
/*out*/ bool& understood);
static inline Result CertID(der::Input& input,
static inline Result CertID(Input& input,
const Context& context,
/*out*/ bool& match);
static Result MatchKeyHash(TrustDomain& trustDomain,
@ -195,7 +195,7 @@ MatchResponderID(TrustDomain& trustDomain,
case ResponderIDType::byKey:
{
der::Input responderID;
Input responderID;
Result rv = responderID.Init(responderIDItem.data, responderIDItem.len);
if (rv != Success) {
return rv;
@ -308,7 +308,7 @@ VerifyEncodedOCSPResponse(TrustDomain& trustDomain, const struct CertID& certID,
// Always initialize this to something reasonable.
expired = false;
der::Input input;
Input input;
if (input.Init(encodedResponse.data, encodedResponse.len) != Success) {
SetErrorToMalformedResponseOnBadDERError();
return SECFailure;
@ -354,7 +354,7 @@ VerifyEncodedOCSPResponse(TrustDomain& trustDomain, const struct CertID& certID,
// responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
//
static inline Result
OCSPResponse(der::Input& input, Context& context)
OCSPResponse(Input& input, Context& context)
{
// OCSPResponseStatus ::= ENUMERATED {
// successful (0), -- Response has valid confirmations
@ -373,12 +373,12 @@ OCSPResponse(der::Input& input, Context& context)
}
switch (responseStatus) {
case 0: break; // successful
case 1: return der::Fail(SEC_ERROR_OCSP_MALFORMED_REQUEST);
case 2: return der::Fail(SEC_ERROR_OCSP_SERVER_ERROR);
case 3: return der::Fail(SEC_ERROR_OCSP_TRY_SERVER_LATER);
case 5: return der::Fail(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
case 6: return der::Fail(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
default: return der::Fail(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
case 1: return Fail(SEC_ERROR_OCSP_MALFORMED_REQUEST);
case 2: return Fail(SEC_ERROR_OCSP_SERVER_ERROR);
case 3: return Fail(SEC_ERROR_OCSP_TRY_SERVER_LATER);
case 5: return Fail(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
case 6: return Fail(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
default: return Fail(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
}
return der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
@ -389,7 +389,7 @@ OCSPResponse(der::Input& input, Context& context)
// responseType OBJECT IDENTIFIER,
// response OCTET STRING }
static inline Result
ResponseBytes(der::Input& input, Context& context)
ResponseBytes(Input& input, Context& context)
{
static const uint8_t id_pkix_ocsp_basic[] = {
0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
@ -410,9 +410,9 @@ ResponseBytes(der::Input& input, Context& context)
// signature BIT STRING,
// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
Result
BasicResponse(der::Input& input, Context& context)
BasicResponse(Input& input, Context& context)
{
der::Input tbsResponseData;
Input tbsResponseData;
SignedDataWithSignature signedData;
Result rv = der::SignedData(input, tbsResponseData, signedData);
if (rv != Success) {
@ -448,7 +448,7 @@ BasicResponse(der::Input& input, Context& context)
// sequence of certificates
while (!input.AtEnd()) {
if (numCerts == PR_ARRAY_SIZE(certs)) {
return der::Fail(SEC_ERROR_BAD_DER);
return Fail(SEC_ERROR_BAD_DER);
}
rv = der::ExpectTagAndGetTLV(input, der::SEQUENCE, certs[numCerts]);
@ -469,7 +469,7 @@ BasicResponse(der::Input& input, Context& context)
// responses SEQUENCE OF SingleResponse,
// responseExtensions [1] EXPLICIT Extensions OPTIONAL }
static inline Result
ResponseData(der::Input& input, Context& context,
ResponseData(Input& input, Context& context,
const SignedDataWithSignature& signedResponseData,
/*const*/ SECItem* certs, size_t numCerts)
{
@ -480,7 +480,7 @@ ResponseData(der::Input& input, Context& context,
}
if (version != der::Version::v1) {
// TODO: more specific error code for bad version?
return der::Fail(SEC_ERROR_BAD_DER);
return Fail(SEC_ERROR_BAD_DER);
}
// ResponderID ::= CHOICE {
@ -491,8 +491,8 @@ ResponseData(der::Input& input, Context& context,
= input.Peek(static_cast<uint8_t>(ResponderIDType::byName))
? ResponderIDType::byName
: ResponderIDType::byKey;
rv = ExpectTagAndGetValue(input, static_cast<uint8_t>(responderIDType),
responderID);
rv = der::ExpectTagAndGetValue(input, static_cast<uint8_t>(responderIDType),
responderID);
if (rv != Success) {
return rv;
}
@ -538,7 +538,7 @@ ResponseData(der::Input& input, Context& context,
// CrlEntryExtensions, ...}
// } OPTIONAL }
static inline Result
SingleResponse(der::Input& input, Context& context)
SingleResponse(Input& input, Context& context)
{
bool match = false;
Result rv = der::Nested(input, der::SEQUENCE,
@ -567,7 +567,8 @@ SingleResponse(der::Input& input, Context& context)
// * revoked overrides good and unknown
// * good overrides unknown
if (input.Peek(static_cast<uint8_t>(CertStatus::Good))) {
rv = ExpectTagAndLength(input, static_cast<uint8_t>(CertStatus::Good), 0);
rv = der::ExpectTagAndLength(input, static_cast<uint8_t>(CertStatus::Good),
0);
if (rv != Success) {
return rv;
}
@ -586,8 +587,8 @@ SingleResponse(der::Input& input, Context& context)
}
context.certStatus = CertStatus::Revoked;
} else {
rv = ExpectTagAndLength(input, static_cast<uint8_t>(CertStatus::Unknown),
0);
rv = der::ExpectTagAndLength(input,
static_cast<uint8_t>(CertStatus::Unknown), 0);
if (rv != Success) {
return rv;
}
@ -610,7 +611,7 @@ SingleResponse(der::Input& input, Context& context)
}
if (thisUpdate > context.time + SLOP) {
return der::Fail(SEC_ERROR_OCSP_FUTURE_RESPONSE);
return Fail(SEC_ERROR_OCSP_FUTURE_RESPONSE);
}
PRTime notAfter;
@ -625,7 +626,7 @@ SingleResponse(der::Input& input, Context& context)
}
if (nextUpdate < thisUpdate) {
return der::Fail(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
return Fail(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
}
if (nextUpdate - thisUpdate <= maxLifetime) {
notAfter = nextUpdate;
@ -639,7 +640,7 @@ SingleResponse(der::Input& input, Context& context)
}
if (context.time < SLOP) { // prevent underflow
return der::Fail(SEC_ERROR_INVALID_ARGS);
return Fail(SEC_ERROR_INVALID_ARGS);
}
if (context.time - SLOP > notAfter) {
@ -669,7 +670,7 @@ SingleResponse(der::Input& input, Context& context)
// issuerKeyHash OCTET STRING, -- Hash of issuer's public key
// serialNumber CertificateSerialNumber }
static inline Result
CertID(der::Input& input, const Context& context, /*out*/ bool& match)
CertID(Input& input, const Context& context, /*out*/ bool& match)
{
match = false;
@ -719,7 +720,7 @@ CertID(der::Input& input, const Context& context, /*out*/ bool& match)
}
if (issuerNameHash.len != TrustDomain::DIGEST_LENGTH) {
return der::Fail(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
return Fail(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
}
// From http://tools.ietf.org/html/rfc6960#section-4.1.1:
@ -782,12 +783,12 @@ KeyHash(TrustDomain& trustDomain, const SECItem& subjectPublicKeyInfo,
// algorithm AlgorithmIdentifier,
// subjectPublicKey BIT STRING }
der::Input spki;
Input spki;
{
// The scope of input is limited to reduce the possibility of confusing it
// with spki in places we need to be using spki below.
der::Input input;
Input input;
if (input.Init(subjectPublicKeyInfo.data, subjectPublicKeyInfo.len)
!= Success) {
return MapSECStatus(SECFailure);
@ -831,7 +832,7 @@ KeyHash(TrustDomain& trustDomain, const SECItem& subjectPublicKeyInfo,
}
Result
ExtensionNotUnderstood(der::Input& /*extnID*/, const SECItem& /*extnValue*/,
ExtensionNotUnderstood(Input& /*extnID*/, const SECItem& /*extnValue*/,
/*out*/ bool& understood)
{
understood = false;

View File

@ -25,7 +25,6 @@
#ifndef mozilla_pkix__pkixutil_h
#define mozilla_pkix__pkixutil_h
#include "pkix/Result.h"
#include "pkixder.h"
#include "prerror.h"
#include "seccomon.h"
@ -144,7 +143,7 @@ private:
NonOwningSECItem nameConstraints;
NonOwningSECItem subjectAltName;
Result RememberExtension(der::Input& extnID, const SECItem& extnValue,
Result RememberExtension(Input& extnID, const SECItem& extnValue,
/*out*/ bool& understood);
BackCert(const BackCert&) /* = delete */;
@ -171,7 +170,7 @@ public:
Result Append(const SECItem& der)
{
if (numItems >= MAX_LENGTH) {
return Fail(RecoverableError, SEC_ERROR_INVALID_ARGS);
return Fail(SEC_ERROR_INVALID_ARGS);
}
items[numItems] = &der;
++numItems;

View File

@ -163,10 +163,10 @@ public:
PR_ASSERT(item->data);
if (numItems >= MaxSequenceItems) {
return der::Fail(SEC_ERROR_INVALID_ARGS);
return Fail(SEC_ERROR_INVALID_ARGS);
}
if (length + item->len > 65535) {
return der::Fail(SEC_ERROR_INVALID_ARGS);
return Fail(SEC_ERROR_INVALID_ARGS);
}
contents[numItems] = item;