Result PathBuildingStep::RecordResult(Result newResult, /*out*/ bool& keepGoing) { if (newResult == Result::ERROR_UNTRUSTED_CERT) { newResult = Result::ERROR_UNTRUSTED_ISSUER; } else if (newResult == Result::ERROR_EXPIRED_CERTIFICATE) { newResult = Result::ERROR_EXPIRED_ISSUER_CERTIFICATE; } if (resultWasSet) { if (result == Success) { return NotReached("RecordResult called after finding a chain", Result::FATAL_ERROR_INVALID_STATE); } // If every potential issuer has the same problem (e.g. expired) and/or if // there is only one bad potential issuer, then return a more specific // error. Otherwise, punt on trying to decide which error should be // returned by returning the generic Result::ERROR_UNKNOWN_ISSUER error. if (newResult != Success && newResult != result) { newResult = Result::ERROR_UNKNOWN_ISSUER; } } result = newResult; resultWasSet = true; keepGoing = result != Success; return Success; }
void tcCheck(TConst tc) { Bool result; AbLogic known; extern AbLogic abCondKnown; listPush(TConst, tc, tcStack); switch (tcTag(tc)) { case TC_Satisfies: known = abCondKnown; abCondKnown = tcKnown(tc); result = tfSatisfies1(tc->ab0, tcArgv(tc)[0], tcArgv(tc)[1]); abCondKnown = known; break; default: bugBadCase(tcTag(tc)); NotReached(result = false); } listPop(TConst, tc, tcStack, tcEq); if (!result) { if (DEBUG(tc)) { tcPrint(dbOut, tc); fnewline(dbOut); } tiTopFns()->terrorTypeConstFailed(tc); } }
/* * Get the declaration object for a global, parameter or local. */ local Foam gl0GetDecl(Foam foam) { int ix; Foam decl; switch (foamTag(foam)) { case FOAM_Glo: ix = foam->foamGlo.index; decl = glvDGlo->foamDDecl.argv[ix]; break; case FOAM_Const: ix = foam->foamConst.index; decl = glvDConst->foamDDecl.argv[ix]; break; case FOAM_Par: ix = foam->foamPar.index; decl = glvDPar->foamDDecl.argv[ix]; break; case FOAM_Loc: ix = foam->foamLoc.index; decl = glvDLoc->foamDDecl.argv[ix]; break; default: bugBadCase(foamTag(foam)); NotReached(decl = 0); } assert(foamTag(decl) == FOAM_Decl || foamTag(decl) == FOAM_GDecl); return decl; }
MostAlignedType * compStoreError(int errnum) { int stoerr; switch (errnum) { case StoErr_OutOfMemory: stoerr = ALDOR_F_StoOutOfMemory; break; case StoErr_UsedNonalloc: stoerr = ALDOR_F_StoUsedNonalloc; break; case StoErr_CantBuild: stoerr = ALDOR_F_StoCantBuild; break; case StoErr_FreeBad: stoerr = ALDOR_F_StoFreeBad; break; default: bugBadCase(errnum); NotReached(stoerr = 0); } if (comsgOkBreakLoop()) bloopMsgFPrintf(osStdout, stoerr); comsgFatal(NULL, stoerr); NotReached(return 0); }
CommandLine::DefaultSwitchPrefix CommandLine::GetDefaultSwitchPrefix() const { for (int i = 0; i < _countof(kSwitchPrefixes); ++i) { if (wcscmp(default_switch_prefix_.data(), kSwitchPrefixes[i]) == 0) { return static_cast<DefaultSwitchPrefix>(i); } } // Shall never get here. ENSURE(CHECK, NotReached())(default_switch_prefix_.data()).Require(); return DefaultSwitchPrefix::PREFIX_DASH; }
/* * Create the symbol for an identifier, given the level, index and string */ local SExpr gl0Id(FoamTag tag, int idx, String str) { String buf; if (*str) switch (tag) { case FOAM_Glo: buf = strPrintf("G-%s", str); break; case FOAM_Const: buf = strPrintf("C%d-%s", idx, str); break; case FOAM_Par: buf = strPrintf("P%d-%s", idx, str); break; case FOAM_Loc: buf = strPrintf("T%d-%s", idx, str); break; default: bugBadCase(tag); NotReached(buf = 0); } else switch (tag) { case FOAM_Glo: bugBadCase(tag); NotReached(buf = 0); break; case FOAM_Const: buf = strPrintf("C%d", idx); break; case FOAM_Par: buf = strPrintf("P%d", idx); break; case FOAM_Loc: buf = strPrintf("T%d", idx); break; default: bugBadCase(tag); NotReached(buf = 0); } return sxiFrSymbol(symIntern(buf)); }
int TLSConnectionPrivate::SSLVerifyCallback(X509_STORE_CTX *ctx, void *udata) { TLSConnectionPrivate *cp = static_cast<TLSConnectionPrivate *>(udata); X509 *cert = ctx->cert; STACK_OF(X509) *chain = ctx->untrusted; std::list<X509Certificate> verification_chain; int ncerts = sk_X509_num(chain); for (int i = 0; i < ncerts; i++) { cert = sk_X509_value(chain, i); int buflen = i2d_X509(cert, NULL); ByteArray cert_der(buflen); char *tmp = cert_der.Data(); int err = i2d_X509(cert, reinterpret_cast<unsigned char **>(&tmp)); if (err == 0) { cp->ShutdownError(OpenSSLUtils::ErrorFromLastCryptoError()); return 0; } X509Certificate parsed_cert = X509Certificate::FromRawDERData(cert_der); verification_chain.push_back(parsed_cert); } std::vector<X509Certificate> verification_vector(verification_chain.begin(), verification_chain.end()); if (cp->chain_verify_handler_) { bool ok = cp->chain_verify_handler_(verification_vector); if (ok) { return 1; } return 0; } else { X509Verifier &v = X509Verifier::SystemVerifier(); X509VerifierOptions opts; opts.dns_name = std::string("www.google.com"); opts.time = std::time(nullptr); bool ok = v.VerifyChain(verification_vector, opts); if (ok) { return 1; } return 0; } NotReached(); }
bool TLSConnectionPrivate::HandleStarvedConnectState() { int err = SSL_connect(ssl_); if (err < 0) { int SSLerr = SSL_get_error(ssl_, err); if (SSLerr != SSL_ERROR_WANT_READ && SSLerr != SSL_ERROR_WANT_WRITE) { ShutdownError(OpenSSLUtils::ErrorFromOpenSSLErrorCode(SSLerr)); return false; } return false; } else if (err == 0) { ShutdownRemote(); return false; } else if (err == 1) { TransitionToConnectionEstablishedState(); return true; } NotReached(); }
void TLSConnectionPrivate::TLSConnectionThread(void *udata) { TLSConnectionPrivate *cp = static_cast<TLSConnectionPrivate *>(udata); cp->thread_id_.store(uv_thread_self()); uv_loop_t *loop = cp->loop_; int err; err = uv_run(loop, UV_RUN_DEFAULT); if (err != UV_OK) { cp->state_ = TLS_CONNECTION_STATE_DISCONNECTED_ERROR; cp->err_ = UVUtils::ErrorFromLastUVError(loop); } cp->thread_id_.store(0); uv_loop_delete(loop); uv_mutex_lock(&cp->wqlock_); cp->wq_ = std::queue<ByteArray>(); uv_mutex_unlock(&cp->wqlock_); switch (cp->state_) { case TLS_CONNECTION_STATE_DISCONNECTED_LOCAL: if (cp->disconnect_handler_) { cp->disconnect_handler_(true); } break; case TLS_CONNECTION_STATE_DISCONNECTED_REMOTE: if (cp->disconnect_handler_) { cp->disconnect_handler_(false); } break; case TLS_CONNECTION_STATE_DISCONNECTED_ERROR: if (cp->error_handler_) { cp->error_handler_(cp->err_); } break; default: NotReached(); } }
Result VerifyEncodedOCSPResponse(TrustDomain& trustDomain, const struct CertID& certID, Time time, uint16_t maxOCSPLifetimeInDays, Input encodedResponse, /*out*/ bool& expired, /*optional out*/ Time* thisUpdate, /*optional out*/ Time* validThrough) { // Always initialize this to something reasonable. expired = false; Context context(trustDomain, certID, time, maxOCSPLifetimeInDays, thisUpdate, validThrough); Reader input(encodedResponse); Result rv = der::Nested(input, der::SEQUENCE, bind(OCSPResponse, _1, ref(context))); if (rv != Success) { return MapBadDERToMalformedOCSPResponse(rv); } rv = der::End(input); if (rv != Success) { return MapBadDERToMalformedOCSPResponse(rv); } expired = context.expired; switch (context.certStatus) { case CertStatus::Good: if (expired) { return Result::ERROR_OCSP_OLD_RESPONSE; } return Success; case CertStatus::Revoked: return Result::ERROR_REVOKED_CERTIFICATE; case CertStatus::Unknown: return Result::ERROR_OCSP_UNKNOWN_CERT; } return NotReached("unknown CertStatus", Result::ERROR_OCSP_UNKNOWN_CERT); }
// Recursively build the path from the given subject certificate to the root. // // Be very careful about changing the order of checks. The order is significant // because it affects which error we return when a certificate or certificate // chain has multiple problems. See the error ranking documentation in // pkix/pkix.h. static Result BuildForward(TrustDomain& trustDomain, const BackCert& subject, Time time, KeyUsage requiredKeyUsageIfPresent, KeyPurposeId requiredEKUIfPresent, const CertPolicyId& requiredPolicy, /*optional*/ const Input* stapledOCSPResponse, unsigned int subCACount) { Result rv; TrustLevel trustLevel; // If this is an end-entity and not a trust anchor, we defer reporting // any error found here until after attempting to find a valid chain. // See the explanation of error prioritization in pkix.h. rv = CheckIssuerIndependentProperties(trustDomain, subject, time, requiredKeyUsageIfPresent, requiredEKUIfPresent, requiredPolicy, subCACount, trustLevel); Result deferredEndEntityError = Success; if (rv != Success) { if (subject.endEntityOrCA == EndEntityOrCA::MustBeEndEntity && trustLevel != TrustLevel::TrustAnchor) { deferredEndEntityError = rv; } else { return rv; } } if (trustLevel == TrustLevel::TrustAnchor) { // End of the recursion. NonOwningDERArray chain; for (const BackCert* cert = &subject; cert; cert = cert->childCert) { rv = chain.Append(cert->GetDER()); if (rv != Success) { return NotReached("NonOwningDERArray::SetItem failed.", rv); } } // This must be done here, after the chain is built but before any // revocation checks have been done. return trustDomain.IsChainValid(chain, time); } if (subject.endEntityOrCA == EndEntityOrCA::MustBeCA) { // Avoid stack overflows and poor performance by limiting cert chain // length. static const unsigned int MAX_SUBCA_COUNT = 6; static_assert(1/*end-entity*/ + MAX_SUBCA_COUNT + 1/*root*/ == NonOwningDERArray::MAX_LENGTH, "MAX_SUBCA_COUNT and NonOwningDERArray::MAX_LENGTH mismatch."); if (subCACount >= MAX_SUBCA_COUNT) { return Result::ERROR_UNKNOWN_ISSUER; } ++subCACount; } else { assert(subCACount == 0); } // Find a trusted issuer. PathBuildingStep pathBuilder(trustDomain, subject, time, requiredEKUIfPresent, requiredPolicy, stapledOCSPResponse, subCACount); // TODO(bug 965136): Add SKI/AKI matching optimizations rv = trustDomain.FindIssuer(subject.GetIssuer(), pathBuilder, time); if (rv != Success) { return rv; } rv = pathBuilder.CheckResult(); if (rv != Success) { return rv; } // If we found a valid chain but deferred reporting an error with the // end-entity certificate, report it now. if (deferredEndEntityError != Success) { return deferredEndEntityError; } // We've built a valid chain from the subject cert up to a trusted root. return Success; }
SExpr compSExprError(SrcPos spos, int errnum, va_list argp) { Msg msg; switch (errnum) { case SX_ErrPackageExists: msg = ALDOR_F_SxPackageExists; break; case SX_ErrInternNeeds: msg = ALDOR_F_SxInternNeeds; break; case SX_ErrNumDenNeeds: msg = ALDOR_F_SxNumDenNeeds; break; case SX_ErrNReverseNeeds: msg = ALDOR_F_SxNReverseNeeds; break; case SX_ErrBadArgumentTo: msg = ALDOR_F_SxBadArgumentTo; break; case SX_ErrReadEOF: msg = ALDOR_F_SxReadEOF; break; case SX_ErrBadPunct: msg = ALDOR_F_SxBadPunct; break; case SX_ErrBadChar: msg = ALDOR_F_SxBadChar; break; case SX_ErrMacroIlleg: msg = ALDOR_F_SxMacroIlleg; break; case SX_ErrMacroUndef: msg = ALDOR_F_SxMacroUndef; break; case SX_ErrMacroUnimp: msg = ALDOR_F_SxMacroUnimp; break; case SX_ErrCantMacroArg: msg = ALDOR_F_SxCantMacroArg; break; case SX_ErrMustMacroArg: msg = ALDOR_F_SxMustMacroArg; break; case SX_ErrBadFeatureForm: msg = ALDOR_F_SxBadFeatureForm; break; case SX_ErrTooManyElts: msg = ALDOR_F_SxTooManyElts; break; case SX_ErrCantShare: msg = ALDOR_F_SxCantShare; break; case SX_ErrAlreadyShare: msg = ALDOR_F_SxAlreadyShare; break; case SX_ErrBadCharName: msg = ALDOR_F_SxBadCharName; break; case SX_ErrBadComplexNum: msg = ALDOR_F_SxBadComplexNum; break; case SX_ErrBadToken: msg = ALDOR_F_SxBadToken; break; case SX_ErrBadPotNum: msg = ALDOR_F_SxBadPotNum; break; case SX_ErrBadUninterned: msg = ALDOR_F_SxBadUninterned; break; default: bugBadCase(errnum); NotReached(msg = 0); } comsgVFatal(abNewNothing(spos), msg, argp); NotReached(return 0); }
// We parse GeneralizedTime and UTCTime according to RFC 5280 and we do not // accept all time formats allowed in the ASN.1 spec. That is, // GeneralizedTime must always be in the format YYYYMMDDHHMMSSZ and UTCTime // must always be in the format YYMMDDHHMMSSZ. Timezone formats of the form // +HH:MM or -HH:MM or NOT accepted. Result TimeChoice(Reader& tagged, uint8_t expectedTag, /*out*/ Time& time) { unsigned int days; Reader input; Result rv = ExpectTagAndGetValue(tagged, expectedTag, input); if (rv != Success) { return rv; } unsigned int yearHi; unsigned int yearLo; if (expectedTag == GENERALIZED_TIME) { rv = ReadTwoDigits(input, 0, 99, yearHi); if (rv != Success) { return rv; } rv = ReadTwoDigits(input, 0, 99, yearLo); if (rv != Success) { return rv; } } else if (expectedTag == UTCTime) { rv = ReadTwoDigits(input, 0, 99, yearLo); if (rv != Success) { return rv; } yearHi = yearLo >= 50u ? 19u : 20u; } else { return NotReached("invalid tag given to TimeChoice", Result::ERROR_INVALID_TIME); } unsigned int year = (yearHi * 100u) + yearLo; if (year < 1970u) { // We don't support dates before January 1, 1970 because that is the epoch. return Result::ERROR_INVALID_TIME; } days = DaysBeforeYear(year); unsigned int month; rv = ReadTwoDigits(input, 1u, 12u, month); if (rv != Success) { return rv; } unsigned int daysInMonth; static const unsigned int jan = 31u; const unsigned int feb = ((year % 4u == 0u) && ((year % 100u != 0u) || (year % 400u == 0u))) ? 29u : 28u; static const unsigned int mar = 31u; static const unsigned int apr = 30u; static const unsigned int may = 31u; static const unsigned int jun = 30u; static const unsigned int jul = 31u; static const unsigned int aug = 31u; static const unsigned int sep = 30u; static const unsigned int oct = 31u; static const unsigned int nov = 30u; static const unsigned int dec = 31u; switch (month) { case 1: daysInMonth = jan; break; case 2: daysInMonth = feb; days += jan; break; case 3: daysInMonth = mar; days += jan + feb; break; case 4: daysInMonth = apr; days += jan + feb + mar; break; case 5: daysInMonth = may; days += jan + feb + mar + apr; break; case 6: daysInMonth = jun; days += jan + feb + mar + apr + may; break; case 7: daysInMonth = jul; days += jan + feb + mar + apr + may + jun; break; case 8: daysInMonth = aug; days += jan + feb + mar + apr + may + jun + jul; break; case 9: daysInMonth = sep; days += jan + feb + mar + apr + may + jun + jul + aug; break; case 10: daysInMonth = oct; days += jan + feb + mar + apr + may + jun + jul + aug + sep; break; case 11: daysInMonth = nov; days += jan + feb + mar + apr + may + jun + jul + aug + sep + oct; break; case 12: daysInMonth = dec; days += jan + feb + mar + apr + may + jun + jul + aug + sep + oct + nov; break; default: return NotReached("month already bounds-checked by ReadTwoDigits", Result::FATAL_ERROR_INVALID_STATE); } unsigned int dayOfMonth; rv = ReadTwoDigits(input, 1u, daysInMonth, dayOfMonth); if (rv != Success) { return rv; } days += dayOfMonth - 1; unsigned int hours; rv = ReadTwoDigits(input, 0u, 23u, hours); if (rv != Success) { return rv; } unsigned int minutes; rv = ReadTwoDigits(input, 0u, 59u, minutes); if (rv != Success) { return rv; } unsigned int seconds; rv = ReadTwoDigits(input, 0u, 59u, seconds); if (rv != Success) { return rv; } uint8_t b; if (input.Read(b) != Success) { return Result::ERROR_INVALID_TIME; } if (b != 'Z') { return Result::ERROR_INVALID_TIME; } if (End(input) != Success) { return Result::ERROR_INVALID_TIME; } uint64_t totalSeconds = (static_cast<uint64_t>(days) * 24u * 60u * 60u) + (static_cast<uint64_t>(hours) * 60u * 60u) + (static_cast<uint64_t>(minutes) * 60u) + seconds; time = TimeFromElapsedSecondsAD(totalSeconds); return Success; }
static Result MatchEKU(Reader& value, KeyPurposeId requiredEKU, EndEntityOrCA endEntityOrCA, /*in/out*/ bool& found, /*in/out*/ bool& foundOCSPSigning) { // See Section 5.9 of "A Layman's Guide to a Subset of ASN.1, BER, and DER" // for a description of ASN.1 DER encoding of OIDs. // id-pkix OBJECT IDENTIFIER ::= // { iso(1) identified-organization(3) dod(6) internet(1) // security(5) mechanisms(5) pkix(7) } // id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } // id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } // id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } // id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } // id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } // id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } static const uint8_t server[] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 1 }; static const uint8_t client[] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 2 }; static const uint8_t code [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 3 }; static const uint8_t email [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 4 }; static const uint8_t ocsp [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 9 }; // id-Netscape OBJECT IDENTIFIER ::= { 2 16 840 1 113730 } // id-Netscape-policy OBJECT IDENTIFIER ::= { id-Netscape 4 } // id-Netscape-stepUp OBJECT IDENTIFIER ::= { id-Netscape-policy 1 } static const uint8_t serverStepUp[] = { (40*2)+16, 128+6,72, 1, 128+6,128+120,66, 4, 1 }; bool match = false; if (!found) { switch (requiredEKU) { case KeyPurposeId::id_kp_serverAuth: // Treat CA certs with step-up OID as also having SSL server type. // Comodo has issued certificates that require this behavior that don't // expire until June 2020! TODO(bug 982932): Limit this exception to // old certificates. match = value.MatchRest(server) || (endEntityOrCA == EndEntityOrCA::MustBeCA && value.MatchRest(serverStepUp)); break; case KeyPurposeId::id_kp_clientAuth: match = value.MatchRest(client); break; case KeyPurposeId::id_kp_codeSigning: match = value.MatchRest(code); break; case KeyPurposeId::id_kp_emailProtection: match = value.MatchRest(email); break; case KeyPurposeId::id_kp_OCSPSigning: match = value.MatchRest(ocsp); break; case KeyPurposeId::anyExtendedKeyUsage: return NotReached("anyExtendedKeyUsage should start with found==true", Result::FATAL_ERROR_LIBRARY_FAILURE); default: return NotReached("unrecognized EKU", Result::FATAL_ERROR_LIBRARY_FAILURE); } } if (match) { found = true; if (requiredEKU == KeyPurposeId::id_kp_OCSPSigning) { foundOCSPSigning = true; } } else if (value.MatchRest(ocsp)) { foundOCSPSigning = true; } value.SkipToEnd(); // ignore unmatched OIDs. return Success; }
local SrcLineList inclFile(String fname, Bool reincluding, Bool top, long *pnlines) { Scope("inclFile"); SrcLineList sll; Hash fhash; FileName fn; FileState o_fileState; IfState fluid(ifState); String curdir; o_fileState = fileState; /* no fluid(struct) */ ifState = NoIf; fileState.lineNumber = 0; fn = inclFind(fname, fileState.curDir); if (fn != 0) { fileState.curDir = strCopy(fnameDir(fn)); fileState.curFile = strCopy(fnameUnparseStatic(fn)); fileState.curFname = fn; } curdir = fileState.curDir; if (fn == 0) { fileState = o_fileState; if (top) { comsgFatal(NULL, ALDOR_F_CantOpen, fname); NotReached(sll = 0); } else sll = inclError(ALDOR_F_CantOpen, fname); } else { fhash = fileHash(fn); fname = strCopy (fnameUnparseStatic(fn)); if (!reincluding && listMemq(Hash)(includedFileCodes, fhash)) { sll = listNil(SrcLine); } else if (listMemq(Hash)(fileState.fileCodes, fhash)) { String s = inclActiveFileChain (fileState.fileNames, "->"); fileState = o_fileState; sll = inclError(ALDOR_E_InclInfinite, s); strFree(s); } else { includedFileCodes = listCons(Hash) (fhash,includedFileCodes); fileState.fileCodes = listCons(Hash) (fhash,fileState.fileCodes); fileState.fileNames = listCons(String)(fname,fileState.fileNames); fileState.infile = fileRdOpen(fn); sll = inclFileContents(); listFreeCons(Hash) (fileState.fileCodes); listFreeCons(String)(fileState.fileNames); fclose(fileState.infile); } fnameFree(fn); strFree(curdir); /*!! curFile is used in src lines */ strFree(fname); } if (pnlines) *pnlines = fileState.lineNumber; fileState = o_fileState; Return(sll); }