security/apps/AppTrustDomain.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/apps/AppTrustDomain.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,186 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifdef MOZ_LOGGING
    1.11 +#define FORCE_PR_LOG 1
    1.12 +#endif
    1.13 +
    1.14 +#include "AppTrustDomain.h"
    1.15 +#include "certdb.h"
    1.16 +#include "pkix/pkix.h"
    1.17 +#include "mozilla/ArrayUtils.h"
    1.18 +#include "nsIX509CertDB.h"
    1.19 +#include "prerror.h"
    1.20 +#include "secerr.h"
    1.21 +
    1.22 +// Generated in Makefile.in
    1.23 +#include "marketplace-prod-public.inc"
    1.24 +#include "marketplace-prod-reviewers.inc"
    1.25 +#include "marketplace-dev-public.inc"
    1.26 +#include "marketplace-dev-reviewers.inc"
    1.27 +#include "xpcshell.inc"
    1.28 +
    1.29 +using namespace mozilla::pkix;
    1.30 +
    1.31 +#ifdef PR_LOGGING
    1.32 +extern PRLogModuleInfo* gPIPNSSLog;
    1.33 +#endif
    1.34 +
    1.35 +namespace mozilla { namespace psm {
    1.36 +
    1.37 +AppTrustDomain::AppTrustDomain(void* pinArg)
    1.38 +  : mPinArg(pinArg)
    1.39 +{
    1.40 +}
    1.41 +
    1.42 +SECStatus
    1.43 +AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot)
    1.44 +{
    1.45 +  SECItem trustedDER;
    1.46 +
    1.47 +  // Load the trusted certificate into the in-memory NSS database so that
    1.48 +  // CERT_CreateSubjectCertList can find it.
    1.49 +
    1.50 +  switch (trustedRoot)
    1.51 +  {
    1.52 +    case nsIX509CertDB::AppMarketplaceProdPublicRoot:
    1.53 +      trustedDER.data = const_cast<uint8_t*>(marketplaceProdPublicRoot);
    1.54 +      trustedDER.len = mozilla::ArrayLength(marketplaceProdPublicRoot);
    1.55 +      break;
    1.56 +
    1.57 +    case nsIX509CertDB::AppMarketplaceProdReviewersRoot:
    1.58 +      trustedDER.data = const_cast<uint8_t*>(marketplaceProdReviewersRoot);
    1.59 +      trustedDER.len = mozilla::ArrayLength(marketplaceProdReviewersRoot);
    1.60 +      break;
    1.61 +
    1.62 +    case nsIX509CertDB::AppMarketplaceDevPublicRoot:
    1.63 +      trustedDER.data = const_cast<uint8_t*>(marketplaceDevPublicRoot);
    1.64 +      trustedDER.len = mozilla::ArrayLength(marketplaceDevPublicRoot);
    1.65 +      break;
    1.66 +
    1.67 +    case nsIX509CertDB::AppMarketplaceDevReviewersRoot:
    1.68 +      trustedDER.data = const_cast<uint8_t*>(marketplaceDevReviewersRoot);
    1.69 +      trustedDER.len = mozilla::ArrayLength(marketplaceDevReviewersRoot);
    1.70 +      break;
    1.71 +
    1.72 +    case nsIX509CertDB::AppXPCShellRoot:
    1.73 +      trustedDER.data = const_cast<uint8_t*>(xpcshellRoot);
    1.74 +      trustedDER.len = mozilla::ArrayLength(xpcshellRoot);
    1.75 +      break;
    1.76 +
    1.77 +    default:
    1.78 +      PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
    1.79 +      return SECFailure;
    1.80 +  }
    1.81 +
    1.82 +  mTrustedRoot = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
    1.83 +                                         &trustedDER, nullptr, false, true);
    1.84 +  if (!mTrustedRoot) {
    1.85 +    return SECFailure;
    1.86 +  }
    1.87 +
    1.88 +  return SECSuccess;
    1.89 +}
    1.90 +
    1.91 +SECStatus
    1.92 +AppTrustDomain::FindPotentialIssuers(const SECItem* encodedIssuerName,
    1.93 +                                     PRTime time,
    1.94 +                             /*out*/ mozilla::pkix::ScopedCERTCertList& results)
    1.95 +{
    1.96 +  MOZ_ASSERT(mTrustedRoot);
    1.97 +  if (!mTrustedRoot) {
    1.98 +    PR_SetError(PR_INVALID_STATE_ERROR, 0);
    1.99 +    return SECFailure;
   1.100 +  }
   1.101 +
   1.102 +  results = CERT_CreateSubjectCertList(nullptr, CERT_GetDefaultCertDB(),
   1.103 +                                       encodedIssuerName, time, true);
   1.104 +  return SECSuccess;
   1.105 +}
   1.106 +
   1.107 +SECStatus
   1.108 +AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
   1.109 +                             SECOidTag policy,
   1.110 +                             const CERTCertificate* candidateCert,
   1.111 +                     /*out*/ TrustLevel* trustLevel)
   1.112 +{
   1.113 +  MOZ_ASSERT(policy == SEC_OID_X509_ANY_POLICY);
   1.114 +  MOZ_ASSERT(candidateCert);
   1.115 +  MOZ_ASSERT(trustLevel);
   1.116 +  MOZ_ASSERT(mTrustedRoot);
   1.117 +  if (!candidateCert || !trustLevel || policy != SEC_OID_X509_ANY_POLICY) {
   1.118 +    PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
   1.119 +    return SECFailure;
   1.120 +  }
   1.121 +  if (!mTrustedRoot) {
   1.122 +    PR_SetError(PR_INVALID_STATE_ERROR, 0);
   1.123 +    return SECFailure;
   1.124 +  }
   1.125 +
   1.126 +  // Handle active distrust of the certificate.
   1.127 +  CERTCertTrust trust;
   1.128 +  if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
   1.129 +    PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, trustObjectSigning);
   1.130 +
   1.131 +    // For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
   1.132 +    // because we can have active distrust for either type of cert. Note that
   1.133 +    // CERTDB_TERMINAL_RECORD means "stop trying to inherit trust" so if the
   1.134 +    // relevant trust bit isn't set then that means the cert must be considered
   1.135 +    // distrusted.
   1.136 +    PRUint32 relevantTrustBit = endEntityOrCA == MustBeCA
   1.137 +                              ? CERTDB_TRUSTED_CA
   1.138 +                              : CERTDB_TRUSTED;
   1.139 +    if (((flags & (relevantTrustBit | CERTDB_TERMINAL_RECORD)))
   1.140 +            == CERTDB_TERMINAL_RECORD) {
   1.141 +      *trustLevel = ActivelyDistrusted;
   1.142 +      return SECSuccess;
   1.143 +    }
   1.144 +
   1.145 +#ifdef MOZ_B2G_CERTDATA
   1.146 +    // XXX(Bug 972201): We have to allow the old way of supporting additional
   1.147 +    // roots until we fix bug 889744. Remove this along with the rest of the
   1.148 +    // MOZ_B2G_CERTDATA stuff.
   1.149 +
   1.150 +    // For TRUST, we only use the CERTDB_TRUSTED_CA bit, because Gecko hasn't
   1.151 +    // needed to consider end-entity certs to be their own trust anchors since
   1.152 +    // Gecko implemented nsICertOverrideService.
   1.153 +    if (flags & CERTDB_TRUSTED_CA) {
   1.154 +      *trustLevel = TrustAnchor;
   1.155 +      return SECSuccess;
   1.156 +    }
   1.157 +#endif
   1.158 +  }
   1.159 +
   1.160 +  // mTrustedRoot is the only trust anchor for this validation.
   1.161 +  if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert)) {
   1.162 +    *trustLevel = TrustAnchor;
   1.163 +    return SECSuccess;
   1.164 +  }
   1.165 +
   1.166 +  *trustLevel = InheritsTrust;
   1.167 +  return SECSuccess;
   1.168 +}
   1.169 +
   1.170 +SECStatus
   1.171 +AppTrustDomain::VerifySignedData(const CERTSignedData* signedData,
   1.172 +                                  const CERTCertificate* cert)
   1.173 +{
   1.174 +  return ::mozilla::pkix::VerifySignedData(signedData, cert, mPinArg);
   1.175 +}
   1.176 +
   1.177 +SECStatus
   1.178 +AppTrustDomain::CheckRevocation(EndEntityOrCA,
   1.179 +                                const CERTCertificate*,
   1.180 +                                /*const*/ CERTCertificate*,
   1.181 +                                PRTime time,
   1.182 +                                /*optional*/ const SECItem*)
   1.183 +{
   1.184 +  // We don't currently do revocation checking. If we need to distrust an Apps
   1.185 +  // certificate, we will use the active distrust mechanism.
   1.186 +  return SECSuccess;
   1.187 +}
   1.188 +
   1.189 +} }

mercurial