security/apps/AppTrustDomain.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifdef MOZ_LOGGING
     8 #define FORCE_PR_LOG 1
     9 #endif
    11 #include "AppTrustDomain.h"
    12 #include "certdb.h"
    13 #include "pkix/pkix.h"
    14 #include "mozilla/ArrayUtils.h"
    15 #include "nsIX509CertDB.h"
    16 #include "prerror.h"
    17 #include "secerr.h"
    19 // Generated in Makefile.in
    20 #include "marketplace-prod-public.inc"
    21 #include "marketplace-prod-reviewers.inc"
    22 #include "marketplace-dev-public.inc"
    23 #include "marketplace-dev-reviewers.inc"
    24 #include "xpcshell.inc"
    26 using namespace mozilla::pkix;
    28 #ifdef PR_LOGGING
    29 extern PRLogModuleInfo* gPIPNSSLog;
    30 #endif
    32 namespace mozilla { namespace psm {
    34 AppTrustDomain::AppTrustDomain(void* pinArg)
    35   : mPinArg(pinArg)
    36 {
    37 }
    39 SECStatus
    40 AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot)
    41 {
    42   SECItem trustedDER;
    44   // Load the trusted certificate into the in-memory NSS database so that
    45   // CERT_CreateSubjectCertList can find it.
    47   switch (trustedRoot)
    48   {
    49     case nsIX509CertDB::AppMarketplaceProdPublicRoot:
    50       trustedDER.data = const_cast<uint8_t*>(marketplaceProdPublicRoot);
    51       trustedDER.len = mozilla::ArrayLength(marketplaceProdPublicRoot);
    52       break;
    54     case nsIX509CertDB::AppMarketplaceProdReviewersRoot:
    55       trustedDER.data = const_cast<uint8_t*>(marketplaceProdReviewersRoot);
    56       trustedDER.len = mozilla::ArrayLength(marketplaceProdReviewersRoot);
    57       break;
    59     case nsIX509CertDB::AppMarketplaceDevPublicRoot:
    60       trustedDER.data = const_cast<uint8_t*>(marketplaceDevPublicRoot);
    61       trustedDER.len = mozilla::ArrayLength(marketplaceDevPublicRoot);
    62       break;
    64     case nsIX509CertDB::AppMarketplaceDevReviewersRoot:
    65       trustedDER.data = const_cast<uint8_t*>(marketplaceDevReviewersRoot);
    66       trustedDER.len = mozilla::ArrayLength(marketplaceDevReviewersRoot);
    67       break;
    69     case nsIX509CertDB::AppXPCShellRoot:
    70       trustedDER.data = const_cast<uint8_t*>(xpcshellRoot);
    71       trustedDER.len = mozilla::ArrayLength(xpcshellRoot);
    72       break;
    74     default:
    75       PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
    76       return SECFailure;
    77   }
    79   mTrustedRoot = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
    80                                          &trustedDER, nullptr, false, true);
    81   if (!mTrustedRoot) {
    82     return SECFailure;
    83   }
    85   return SECSuccess;
    86 }
    88 SECStatus
    89 AppTrustDomain::FindPotentialIssuers(const SECItem* encodedIssuerName,
    90                                      PRTime time,
    91                              /*out*/ mozilla::pkix::ScopedCERTCertList& results)
    92 {
    93   MOZ_ASSERT(mTrustedRoot);
    94   if (!mTrustedRoot) {
    95     PR_SetError(PR_INVALID_STATE_ERROR, 0);
    96     return SECFailure;
    97   }
    99   results = CERT_CreateSubjectCertList(nullptr, CERT_GetDefaultCertDB(),
   100                                        encodedIssuerName, time, true);
   101   return SECSuccess;
   102 }
   104 SECStatus
   105 AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
   106                              SECOidTag policy,
   107                              const CERTCertificate* candidateCert,
   108                      /*out*/ TrustLevel* trustLevel)
   109 {
   110   MOZ_ASSERT(policy == SEC_OID_X509_ANY_POLICY);
   111   MOZ_ASSERT(candidateCert);
   112   MOZ_ASSERT(trustLevel);
   113   MOZ_ASSERT(mTrustedRoot);
   114   if (!candidateCert || !trustLevel || policy != SEC_OID_X509_ANY_POLICY) {
   115     PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
   116     return SECFailure;
   117   }
   118   if (!mTrustedRoot) {
   119     PR_SetError(PR_INVALID_STATE_ERROR, 0);
   120     return SECFailure;
   121   }
   123   // Handle active distrust of the certificate.
   124   CERTCertTrust trust;
   125   if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
   126     PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, trustObjectSigning);
   128     // For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
   129     // because we can have active distrust for either type of cert. Note that
   130     // CERTDB_TERMINAL_RECORD means "stop trying to inherit trust" so if the
   131     // relevant trust bit isn't set then that means the cert must be considered
   132     // distrusted.
   133     PRUint32 relevantTrustBit = endEntityOrCA == MustBeCA
   134                               ? CERTDB_TRUSTED_CA
   135                               : CERTDB_TRUSTED;
   136     if (((flags & (relevantTrustBit | CERTDB_TERMINAL_RECORD)))
   137             == CERTDB_TERMINAL_RECORD) {
   138       *trustLevel = ActivelyDistrusted;
   139       return SECSuccess;
   140     }
   142 #ifdef MOZ_B2G_CERTDATA
   143     // XXX(Bug 972201): We have to allow the old way of supporting additional
   144     // roots until we fix bug 889744. Remove this along with the rest of the
   145     // MOZ_B2G_CERTDATA stuff.
   147     // For TRUST, we only use the CERTDB_TRUSTED_CA bit, because Gecko hasn't
   148     // needed to consider end-entity certs to be their own trust anchors since
   149     // Gecko implemented nsICertOverrideService.
   150     if (flags & CERTDB_TRUSTED_CA) {
   151       *trustLevel = TrustAnchor;
   152       return SECSuccess;
   153     }
   154 #endif
   155   }
   157   // mTrustedRoot is the only trust anchor for this validation.
   158   if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert)) {
   159     *trustLevel = TrustAnchor;
   160     return SECSuccess;
   161   }
   163   *trustLevel = InheritsTrust;
   164   return SECSuccess;
   165 }
   167 SECStatus
   168 AppTrustDomain::VerifySignedData(const CERTSignedData* signedData,
   169                                   const CERTCertificate* cert)
   170 {
   171   return ::mozilla::pkix::VerifySignedData(signedData, cert, mPinArg);
   172 }
   174 SECStatus
   175 AppTrustDomain::CheckRevocation(EndEntityOrCA,
   176                                 const CERTCertificate*,
   177                                 /*const*/ CERTCertificate*,
   178                                 PRTime time,
   179                                 /*optional*/ const SECItem*)
   180 {
   181   // We don't currently do revocation checking. If we need to distrust an Apps
   182   // certificate, we will use the active distrust mechanism.
   183   return SECSuccess;
   184 }
   186 } }

mercurial