Ejemplo n.º 1
0
nsresult
nsNSSCertificate::GetCertificateHash(nsAString& aFingerprint, SECOidTag aHashAlg)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  aFingerprint.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(aHashAlg, mCert->derCert.data,
                                 mCert->derCert.len);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // CERT_Hexify's second argument is an int that is interpreted as a boolean
  char* fpStr = CERT_Hexify(const_cast<SECItem*>(&digest.get()), 1);
  if (!fpStr) {
    return NS_ERROR_FAILURE;
  }

  aFingerprint.AssignASCII(fpStr);
  PORT_Free(fpStr);
  return NS_OK;
}
Ejemplo n.º 2
0
TS::TS(const string &url, const Digest &digest, const string &useragent)
{
    SCOPE(TS_REQ, req, TS_REQ_new());
    TS_REQ_set_version(req.get(), 1);
    TS_REQ_set_cert_req(req.get(), 1);

    SCOPE(X509_ALGOR, algo, X509_ALGOR_new());
    algo->algorithm = OBJ_nid2obj(Digest::toMethod(digest.uri()));
    algo->parameter = ASN1_TYPE_new();
    algo->parameter->type = V_ASN1_NULL;

    SCOPE(TS_MSG_IMPRINT, msg_imprint, TS_MSG_IMPRINT_new());
    TS_MSG_IMPRINT_set_algo(msg_imprint.get(), algo.get());
    vector<unsigned char> digestdata = digest.result();
    TS_MSG_IMPRINT_set_msg(msg_imprint.get(), digestdata.data(), int(digestdata.size()));
    TS_REQ_set_msg_imprint(req.get(), msg_imprint.get());

#if 0
    if(!policy.empty())
    {
        SCOPE(ASN1_OBJECT, obj, OBJ_txt2obj(policy.c_str(), 0));
        TS_REQ_set_policy_id(req.get(), obj.get());
    }
#endif

    SCOPE(ASN1_INTEGER, nonce, ASN1_INTEGER_new());
    nonce->length = 20;
    nonce->data = (unsigned char*)OPENSSL_malloc(nonce->length);
    nonce->data[0] = 0;
    while(nonce->data[0] == 0) // Make sure that first byte is not 0x00
        RAND_bytes(nonce->data, nonce->length);
    TS_REQ_set_nonce(req.get(), nonce.get());

    int len = i2d_TS_REQ(req.get(), 0);
    vector<unsigned char> data(len, 0);
    unsigned char *p = data.data();
    i2d_TS_REQ(req.get(), &p);

    string result = Connect(url, "POST", 0, useragent).exec({
        {"Content-Type", "application/timestamp-query"},
        {"Accept", "application/timestamp-reply"},
        {"Connection", "Close"},
        {"Cache-Control", "no-cache"}
    }, data).content;

    const unsigned char *p2 = (const unsigned char*)result.c_str();
    SCOPE(TS_RESP, resp, d2i_TS_RESP(0, &p2, long(result.size())));
    if(!resp)
        THROW_OPENSSLEXCEPTION("Failed to parse TS response.");

    SCOPE(TS_VERIFY_CTX, ctx, TS_VERIFY_CTX_new());
    ctx->flags = TS_VFY_NONCE|TS_VFY_VERSION;
    ctx->nonce = nonce.release();
    if(TS_RESP_verify_response(ctx.get(), resp.get()) != 1)
        THROW_OPENSSLEXCEPTION("Failed to verify TS response.");

    d.reset(resp->token, function<void(PKCS7*)>(PKCS7_free));
    resp->token = nullptr;
}
Ejemplo n.º 3
0
zx_status_t merkle_tree_create(const void* data, size_t data_len, void* tree, size_t tree_len,
                               void* out, size_t out_len) {
    zx_status_t rc;
    Digest digest;
    if ((rc = MerkleTree::Create(data, data_len, tree, tree_len, &digest)) != ZX_OK) {
        return rc;
    }
    return digest.CopyTo(static_cast<uint8_t*>(out), out_len);
}
Ejemplo n.º 4
0
NS_IMETHODIMP
nsDataSignatureVerifier::VerifySignature(const char* aRSABuf,
                                         uint32_t aRSABufLen,
                                         const char* aPlaintext,
                                         uint32_t aPlaintextLen,
                                         int32_t* aErrorCode,
                                         nsICertificatePrincipal** aPrincipal)
{
  if (!aPlaintext || !aPrincipal || !aErrorCode) {
    return NS_ERROR_INVALID_ARG;
  }

  *aErrorCode = VERIFY_ERROR_OTHER;
  *aPrincipal = nullptr;

  nsNSSShutDownPreventionLock locker;

  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA1,
                                 reinterpret_cast<const uint8_t*>(aPlaintext),
                                 aPlaintextLen);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  SECItem buffer = {
    siBuffer,
    reinterpret_cast<uint8_t*>(const_cast<char*>(aRSABuf)),
    aRSABufLen
  };

  VerifyCertificateContext context;
  // XXX: pinArg is missing
  rv = VerifyCMSDetachedSignatureIncludingCertificate(buffer, digest.get(),
                                                      VerifyCertificate,
                                                      &context, nullptr);
  if (NS_SUCCEEDED(rv)) {
    *aErrorCode = VERIFY_OK;
  } else if (NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_SECURITY) {
    if (rv == GetXPCOMFromNSSError(SEC_ERROR_UNKNOWN_ISSUER)) {
      *aErrorCode = VERIFY_ERROR_UNKNOWN_ISSUER;
    } else {
      *aErrorCode = VERIFY_ERROR_OTHER;
    }
    rv = NS_OK;
  }
  if (rv == NS_OK) {
    context.principal.forget(aPrincipal);
  }

  return rv;
}
Ejemplo n.º 5
0
std::string DigestEngine::digestToHex(const Digest& bytes)
{
    static const char digits[] = "0123456789abcdef";
    std::string result;
    result.reserve(bytes.size()*2);
    for (Digest::const_iterator it = bytes.begin(); it != bytes.end(); ++it)
    {
        unsigned char c = *it;
        result += digits[(c >> 4) & 0xF];
        result += digits[c & 0xF];
    }
    return result;
}
// Perform a hash of the provided cert, then search in the RootHashes.inc data
// structure for a matching bin number.
int32_t
RootCABinNumber(const SECItem* cert)
{
  Digest digest;

  // Compute SHA256 hash of the certificate
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->data, cert->len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return ROOT_CERTIFICATE_HASH_FAILURE;
  }

  // Compare against list of stored hashes
  size_t idx;

  MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
           ("pkpinTelem: First bytes %02x %02x %02x %02x\n",
            digest.get().data[0], digest.get().data[1], digest.get().data[2], digest.get().data[3]));

  if (mozilla::BinarySearchIf(ROOT_TABLE, 0, ArrayLength(ROOT_TABLE),
        BinaryHashSearchArrayComparator(static_cast<uint8_t*>(digest.get().data),
                                        digest.get().len),
        &idx)) {

    MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
          ("pkpinTelem: Telemetry index was %" PRIuSIZE ", bin is %d\n",
           idx, ROOT_TABLE[idx].binNumber));
    return (int32_t) ROOT_TABLE[idx].binNumber;
  }

  // Didn't match.
  return ROOT_CERTIFICATE_UNKNOWN;
}
// Perform a hash of the provided cert, then search in the RootHashes.inc data
// structure for a matching bin number.
int32_t
RootCABinNumber(const SECItem* cert)
{
  Digest digest;

  // Compute SHA256 hash of the certificate
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->data, cert->len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return HASH_FAILURE;
  }

  // Compare against list of stored hashes
  size_t idx;

  PR_LOG(PublicKeyPinningTelemetryLog(), PR_LOG_DEBUG,
           ("pkpinTelem: First bytes %02hx %02hx %02hx %02hx\n",
            digest.get().data[0], digest.get().data[1], digest.get().data[2], digest.get().data[3]));

  if (mozilla::BinarySearchIf(ROOT_TABLE, 0, ArrayLength(ROOT_TABLE),
          BinaryHashSearchArrayComparator(
            reinterpret_cast<const uint8_t*>(digest.get().data), digest.get().len),
         &idx)) {

    PR_LOG(PublicKeyPinningTelemetryLog(), PR_LOG_DEBUG,
          ("pkpinTelem: Telemetry index was %lu, bin is %d\n",
           idx, ROOT_TABLE[idx].binNumber));
    return (int32_t) ROOT_TABLE[idx].binNumber;
  }

  // Didn't match.
  return UNKNOWN_ROOT;
}
/**
 Computes in the location specified by base64Out the SHA256 digest
 of the DER Encoded subject Public Key Info for the given cert
*/
static nsresult
GetBase64HashSPKI(const CERTCertificate* cert, nsACString& hashSPKIDigest)
{
  hashSPKIDigest.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->derPublicKey.data,
                                 cert->derPublicKey.len);
  if (NS_FAILED(rv)) {
    return rv;
  }
  return Base64Encode(nsDependentCSubstring(
                        reinterpret_cast<const char*>(digest.get().data),
                        digest.get().len),
                      hashSPKIDigest);
}
Ejemplo n.º 9
0
zx_status_t merkle_tree_create_final(merkle_tree_t* mt, void* tree, void* out, size_t out_len) {
    // Must have a wrapper object.
    if (!mt) {
        return ZX_ERR_INVALID_ARGS;
    }
    // Take possession of the wrapper object. That way, we'll clean up
    // automatically.
    fbl::unique_ptr<merkle_tree_t> mt_uniq(mt);
    // Call the C++ function.
    zx_status_t rc;
    Digest digest;
    if ((rc = mt_uniq->obj.CreateFinal(tree, &digest)) != ZX_OK) {
        return rc;
    }
    return digest.CopyTo(static_cast<uint8_t*>(out), out_len);
}
Ejemplo n.º 10
0
Bool SignerReal::notarize( PublicKey pubkey, Signature signature, Digest hash, Monitor& monitor )
{
	if (!check_interface(monitor)) return false;

	eprovider::TheKey thepubkey = creator.getCreatureCurrentTheKey(pubkey);
	Size hashsize;
	RECOVER_CALL(hashsize = iface->getMaxHashSize(thepubkey, error));
	
	Padder curpad = padder;
	if (pubkey.getPadder(Monitor()))
	{
		curpad = pubkey.getPadder(monitor);
	} else if (signature.getPadder(Monitor()))
	{
		curpad = signature.getPadder(monitor);
	} else {
		//TODO: find default padder
	}

	if (curpad.ok() && hashsize.bits()) hash = curpad.pad(hash, hashsize, monitor); if (!monitor) return Bool();
	Data hashblock = hash.asData();
	
	Image signimage = signature.encode(monitor);
	Snapshot signblock = signimage.snapshot();

	Bool result;
	
	RECOVER_CALL( (result = iface->notarizeHash(session,hashblock.get(), hashblock.size(), signblock.get(), signblock.size(), signblock.encid(), thepubkey, error)) );

	return result;
}
Ejemplo n.º 11
0
Signature SignerReal::sign( PrivateKey privkey, Digest hash, Monitor& monitor )
{
	if (!check_interface(monitor)) return Signature();

	Parameters params = privkey.getAlgParams(acSign, Monitor());
	if (params) setAlgParams(params,monitor);

	Padder curpad = padder;
	if (privkey.getPadder(Monitor()))
	{
		curpad = privkey.getPadder(monitor);
	} else {
		//TODO: find default padder
	}

	Error error;
	if (random)
	{
		IRef<eprovider::ProviderInterface> randomer = creator.getCreatureCurrentInterface(random);
		if (randomer) iface->setRandom(session, randomer.cast<eprovider::RandomGenerator>().get(), error);
	}

	eprovider::TheKey thekey = creator.getCreatureCurrentTheKey(privkey);

	Size hashsize = iface->getMaxHashSize(thekey, error);
	if (curpad.ok() && hashsize.bits()) hash = curpad.pad(hash, hashsize, monitor); if (!monitor) return Signature();
	Data hashblock = hash.asData();

	eprovider::Block binsign;
	RECOVER_CALL( (binsign = iface->signHash(session, hashblock.get(), hashblock.size(), thekey, error)) );

	Snapshot snapshot = creator.createSnapshot(binsign.get(), binsign.size(), binsign.encid(), iface->getKeyId(kcSignature));
	return snapshot.reviveSignature(monitor);
}
Ejemplo n.º 12
0
void Session::Impl::SetDigest(const Digest& auth) {
    auto curl = curl_->handle;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
        curl_easy_setopt(curl, CURLOPT_USERPWD, auth.GetAuthString());
    }
}
Ejemplo n.º 13
0
void TS::verify(const Digest &digest)
{
    if(!d)
        THROW_OPENSSLEXCEPTION("Failed to verify TS response.");

    vector<unsigned char> data = digest.result();
    SCOPE(TS_VERIFY_CTX, ctx, TS_VERIFY_CTX_new());
    ctx->flags = TS_VFY_IMPRINT|TS_VFY_VERSION|TS_VFY_SIGNATURE;
    ctx->imprint = data.data();
    ctx->imprint_len = (unsigned int)data.size();

    ctx->store = X509_STORE_new();
    X509CertStore::instance()->activate(cert().issuerName("C"));
    for(const X509Cert &i: X509CertStore::instance()->certs())
        X509_STORE_add_cert(ctx->store, i.handle());
    OpenSSLException(); // Clear errors

    SCOPE(X509_STORE_CTX, csc, X509_STORE_CTX_new());
    if (!csc)
        THROW_OPENSSLEXCEPTION("Failed to create X509_STORE_CTX");

    if(!X509_STORE_CTX_init(csc.get(), ctx->store, 0, 0))
        THROW_OPENSSLEXCEPTION("Failed to init X509_STORE_CTX");

    X509_STORE_set_verify_cb_func(ctx->store, [](int ok, X509_STORE_CTX *ctx) -> int {
        switch(X509_STORE_CTX_get_error(ctx))
        {
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
        case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
        case X509_V_ERR_CERT_UNTRUSTED:
        {
            const vector<X509Cert> &list = X509CertStore::instance()->certs();
            if(find(list.begin(), list.end(), X509Cert(ctx->current_cert)) != list.end())
                return 1;
            return ok;
        }
        default: return ok;
        }
    });

    int err = TS_RESP_verify_token(ctx.get(), d.get());
    //Avoid CRYPTO_free
    ctx->imprint = nullptr;
    ctx->imprint_len = 0;
    if(err != 1)
    {
        long err = ERR_get_error();
        if(ERR_GET_LIB(err) == 47 && ERR_GET_REASON(err) == TS_R_CERTIFICATE_VERIFY_ERROR)
        {
            Exception e(EXCEPTION_PARAMS("Certificate status: unknown"));
            e.setCode( Exception::CertificateUnknown );
            throw e;
        }
        THROW_OPENSSLEXCEPTION("Failed to verify TS response.");
    }
}
/**
 Computes in the location specified by base64Out the SHA256 digest
 of the DER Encoded subject Public Key Info for the given cert
*/
static SECStatus
GetBase64SHA256SPKI(const CERTCertificate* cert,
                    nsACString& aSha256SPKIDigest){
  aSha256SPKIDigest.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->derPublicKey.data,
                                 cert->derPublicKey.len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return SECFailure;
  }
  rv = Base64Encode(nsDependentCSubstring(
                      reinterpret_cast<const char*>(digest.get().data),
                      digest.get().len),
                      aSha256SPKIDigest);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return SECFailure;
  }
  return SECSuccess;
}
Ejemplo n.º 15
0
/**
 * Adds signing certificate to the signature XML. The DER encoded X.509 certificate is added to
 * Signature->KeyInfo->X509Data->X509Certificate. Certificate info is also added to
 * Signature->Object->QualifyingProperties->SignedProperties->SignedSignatureProperties->SigningCertificate.
 *
 * @param cert certificate that is used for signing the signature XML.
 */
void SignatureBES::setSigningCertificate(const X509Cert& x509)
{
    DEBUG("SignatureBES::setSigningCertificate()");
    // Signature->KeyInfo->X509Data->X509Certificate
    // BASE64 encoding of a DER-encoded X.509 certificate = PEM encoded.
    X509DataType x509Data;
    x509Data.x509Certificate().push_back(toBase64(x509));

    KeyInfoType keyInfo;
    keyInfo.x509Data().push_back(x509Data);
    signature->keyInfo(keyInfo);

    // Signature->Object->QualifyingProperties->SignedProperties->SignedSignatureProperties->SigningCertificate
    // Calculate digest of the X.509 certificate.
    Digest digest;
    digest.update(x509);
    CertIDListType signingCertificate;
    signingCertificate.cert().push_back(CertIDType(
        DigestAlgAndValueType(DigestMethodType(digest.uri()), toBase64(digest.result())),
        X509IssuerSerialType(x509.issuerName(), x509.serial())));

    getSignedSignatureProperties().signingCertificate(signingCertificate);
}
Ejemplo n.º 16
0
NS_IMETHODIMP
nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest(nsACString& aSha256SPKIDigest)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  aSha256SPKIDigest.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, mCert->derPublicKey.data,
                                 mCert->derPublicKey.len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  rv = Base64Encode(nsDependentCSubstring(
                      reinterpret_cast<const char*> (digest.get().data),
                      digest.get().len),
                    aSha256SPKIDigest);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  return NS_OK;
}
Ejemplo n.º 17
0
// Called on the worker thread.
bool
BackgroundFileSaver::CheckCompletion()
{
  nsresult rv;

  MOZ_ASSERT(!mAsyncCopyContext,
             "Should not be copying when checking completion conditions.");

  bool failed = true;
  {
    MutexAutoLock lock(mLock);

    if (mComplete) {
      return true;
    }

    // If an error occurred, we don't need to do the checks in this code block,
    // and the operation can be completed immediately with a failure code.
    if (NS_SUCCEEDED(mStatus)) {
      failed = false;

      // We did not incur in an error, so we must determine if we can stop now.
      // If the Finish method has not been called, we can just continue now.
      if (!mFinishRequested) {
        return false;
      }

      // We can only stop when all the operations requested by the control
      // thread have been processed.  First, we check whether we have processed
      // the first SetTarget call, if any.  Then, we check whether we have
      // processed any rename requested by subsequent SetTarget calls.
      if ((mInitialTarget && !mActualTarget) ||
          (mRenamedTarget && mRenamedTarget != mActualTarget)) {
        return false;
      }

      // If we still have data to write to the output file, allow the copy
      // operation to resume.  The Available getter may return an error if one
      // of the pipe's streams has been already closed.
      uint64_t available;
      rv = mPipeInputStream->Available(&available);
      if (NS_SUCCEEDED(rv) && available != 0) {
        return false;
      }
    }

    mComplete = true;
  }

  // Ensure we notify completion now that the operation finished.
  // Do a best-effort attempt to remove the file if required.
  if (failed && mActualTarget && !mActualTargetKeepPartial) {
    (void)mActualTarget->Remove(false);
  }

  // Finish computing the hash
  if (!failed && mDigestContext) {
    nsNSSShutDownPreventionLock lock;
    if (!isAlreadyShutDown()) {
      Digest d;
      rv = d.End(SEC_OID_SHA256, mDigestContext);
      if (NS_SUCCEEDED(rv)) {
        MutexAutoLock lock(mLock);
        mSha256 = nsDependentCSubstring(char_ptr_cast(d.get().data),
                                        d.get().len);
      }
    }
  }

  // Compute the signature of the binary. ExtractSignatureInfo doesn't do
  // anything on non-Windows platforms except return an empty nsIArray.
  if (!failed && mActualTarget) {
    nsString filePath;
    mActualTarget->GetTarget(filePath);
    nsresult rv = ExtractSignatureInfo(filePath);
    if (NS_FAILED(rv)) {
      LOG(("Unable to extract signature information [this = %p].", this));
    } else {
      LOG(("Signature extraction success! [this = %p]", this));
    }
  }

  // Post an event to notify that the operation completed.
  if (NS_FAILED(mControlThread->Dispatch(NewRunnableMethod(this,
                                                           &BackgroundFileSaver::NotifySaveComplete),
                                         NS_DISPATCH_NORMAL))) {
    NS_WARNING("Unable to post completion event to the control thread.");
  }

  return true;
}
Ejemplo n.º 18
0
bool
Digest<Hash>::operator==(Digest<Hash>& digest)
{
  return *computeDigest() == *digest.computeDigest();
}
// Called on the worker thread.
bool
BackgroundFileSaver::CheckCompletion()
{
  nsresult rv;

  MOZ_ASSERT(!mAsyncCopyContext,
             "Should not be copying when checking completion conditions.");

  bool failed = true;
  {
    MutexAutoLock lock(mLock);

    if (mComplete) {
      return true;
    }

    // If an error occurred, we don't need to do the checks in this code block,
    // and the operation can be completed immediately with a failure code.
    if (NS_SUCCEEDED(mStatus)) {
      failed = false;

      // On success, if there is a pending rename operation, we must process it
      // before finishing.  Otherwise, we can finish now if requested.
      if ((mAssignedTarget && mAssignedTarget != mActualTarget) ||
          !mFinishRequested) {
        return false;
      }

      // If completion was requested, but we still have data to write to the
      // output file, allow the copy operation to resume.  The Available getter
      // may return an error if one of the pipe's streams has been already closed.
      uint64_t available;
      rv = mPipeInputStream->Available(&available);
      if (NS_SUCCEEDED(rv) && available != 0) {
        return false;
      }
    }

    mComplete = true;
  }

  // Ensure we notify completion now that the operation finished.
  // Do a best-effort attempt to remove the file if required.
  if (failed && mActualTarget && !mActualTargetKeepPartial) {
    (void)mActualTarget->Remove(false);
  }

  // Finish computing the hash
  if (!failed && mDigestContext) {
    nsNSSShutDownPreventionLock lock;
    if (!isAlreadyShutDown()) {
      Digest d;
      rv = d.End(SEC_OID_SHA256, mDigestContext);
      if (NS_SUCCEEDED(rv)) {
        MutexAutoLock lock(mLock);
        mSha256 = nsDependentCSubstring(char_ptr_cast(d.get().data),
                                        d.get().len);
      }
    }
  }

  // Post an event to notify that the operation completed.
  nsCOMPtr<nsIRunnable> event =
    NS_NewRunnableMethod(this, &BackgroundFileSaver::NotifySaveComplete);
  if (!event ||
      NS_FAILED(mControlThread->Dispatch(event, NS_DISPATCH_NORMAL))) {
    NS_WARNING("Unable to post completion event to the control thread.");
  }

  return true;
}
/*
 * Verify the signature of a directory structure as if it were a
 * signed JAR file (used for unpacked JARs)
 */
nsresult
VerifySignedDirectory(AppTrustedRoot aTrustedRoot,
                      nsIFile* aDirectory,
                      /*out, optional */ nsIX509Cert** aSignerCert)
{
  NS_ENSURE_ARG_POINTER(aDirectory);

  if (aSignerCert) {
    *aSignerCert = nullptr;
  }

  // Make sure there's a META-INF directory

  nsCOMPtr<nsIFile> metaDir;
  nsresult rv = aDirectory->Clone(getter_AddRefs(metaDir));
  if (NS_FAILED(rv)) {
    return rv;
  }
  rv = metaDir->Append(NS_LITERAL_STRING(JAR_META_DIR));
  if (NS_FAILED(rv)) {
    return rv;
  }

  bool exists;
  rv = metaDir->Exists(&exists);
  if (NS_FAILED(rv) || !exists) {
    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
  }
  bool isDirectory;
  rv = metaDir->IsDirectory(&isDirectory);
  if (NS_FAILED(rv) || !isDirectory) {
    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
  }

  // Find and load the Signature (RSA) file

  nsAutoString sigFilename;
  rv = FindSignatureFilename(metaDir, sigFilename);
  if (NS_FAILED(rv)) {
    return rv;
  }

  ScopedAutoSECItem sigBuffer;
  rv = LoadOneMetafile(metaDir, sigFilename, sigBuffer, nullptr);
  if (NS_FAILED(rv)) {
    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
  }

  // Load the signature (SF) file and verify the signature.
  // The .sf and .rsa files must have the same name apart from the extension.

  nsAutoString sfFilename(Substring(sigFilename, 0, sigFilename.Length() - 3)
                          + NS_LITERAL_STRING("sf"));

  ScopedAutoSECItem sfBuffer;
  Digest sfCalculatedDigest;
  rv = LoadOneMetafile(metaDir, sfFilename, sfBuffer, &sfCalculatedDigest);
  if (NS_FAILED(rv)) {
    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
  }

  sigBuffer.type = siBuffer;
  ScopedCERTCertList builtChain;
  rv = VerifySignature(aTrustedRoot, sigBuffer, sfCalculatedDigest.get(),
                       builtChain);
  if (NS_FAILED(rv)) {
    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
  }

  // Get the expected manifest hash from the signed .sf file

  ScopedAutoSECItem mfDigest;
  rv = ParseSF(char_ptr_cast(sfBuffer.data), mfDigest);
  if (NS_FAILED(rv)) {
    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
  }

  // Load manifest (MF) file and verify signature

  nsAutoString mfFilename(NS_LITERAL_STRING("manifest.mf"));
  ScopedAutoSECItem manifestBuffer;
  Digest mfCalculatedDigest;
  rv = LoadOneMetafile(metaDir, mfFilename, manifestBuffer, &mfCalculatedDigest);
  if (NS_FAILED(rv)) {
    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
  }

  if (SECITEM_CompareItem(&mfDigest, &mfCalculatedDigest.get()) != SECEqual) {
    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
  }

  // Parse manifest and verify signed hash of all listed files

  // Allocate the I/O buffer only once per JAR, instead of once per entry, in
  // order to minimize malloc/free calls and in order to avoid fragmenting
  // memory.
  ScopedAutoSECItem buf(128 * 1024);

  nsTHashtable<nsStringHashKey> items;
  rv = ParseMFUnpacked(char_ptr_cast(manifestBuffer.data),
                       aDirectory, items, buf);
  if (NS_FAILED(rv)){
    return rv;
  }

  // We've checked that everything listed in the manifest exists and is signed
  // correctly. Now check on disk for extra (unsigned) files.
  // Deletes found entries from items as it goes.
  rv = CheckDirForUnsignedFiles(aDirectory, EmptyString(), items,
                                sigFilename, sfFilename, mfFilename);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // We verified that every entry that we require to be signed is signed. But,
  // were there any missing entries--that is, entries that are mentioned in the
  // manifest but missing from the directory tree? (There shouldn't be given
  // ParseMFUnpacked() checking them all, but it's a cheap sanity check.)
  if (items.Count() != 0) {
    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
  }

  // Return the signer's certificate to the reader if they want it.
  // XXX: We should return an nsIX509CertList with the whole validated chain.
  if (aSignerCert) {
    MOZ_ASSERT(CERT_LIST_HEAD(builtChain));
    nsCOMPtr<nsIX509Cert> signerCert =
      nsNSSCertificate::Create(CERT_LIST_HEAD(builtChain)->cert);
    NS_ENSURE_TRUE(signerCert, NS_ERROR_OUT_OF_MEMORY);
    signerCert.forget(aSignerCert);
  }

  return NS_OK;
}
Ejemplo n.º 21
0
void runManager::run()
{
	if (runManParam->XML_OUT) {
		fprintf(runManParam->FILEOUTXML, "<spectrumMatchList>\n");
	}
	
	spectrumData = new data();
	memCheck.data++;
	spectrumData->init(runManParam);	
	
	// DIGESTION: static initialization
	IOParam param;
	param.SetEnzyme(runManParam->ENZYME);
	param.m_iMissedClevage	= runManParam->MISSED;
	param.m_eResolution = MASS_MONOISOTOPIC;
	param.m_eIonMode = ION_MODE_M;
	param.m_bPTM = false;
	Digest digest;
	digest.Load(&param);
	
	while (spectrumData->load()) {
		spectrumData->display(runManParam->FILEOUT);
		
		if (runManParam->XML_OUT) {
			spectrumData->displayXML(runManParam->FILEOUTXML);
		}
		
		unsigned long int iniTime = clock();
		
		popitam = new Compare();
		memCheck.popitam++;
		
		// CONSTRUIT LE GRAPHE, DIRIGE LES POINTEURS
		//gfs
		unsigned long int t0 = clock();
		//eof gfs
		popitam->init_POP(runManParam, scoreFunction[runManParam->m_MUTMOD], aaParam,
				   ionParamTOFTOF1, ionParamQTOF1, ionParamQTOF2, ionParamQTOF3,
				   spectrumData, popiResults, allRunStats);
		//gfs
		double dt0 = ((double)(clock()-t0)/(CLOCKS_PER_SEC/1000));
		unsigned long int t1 = clock();
		//eof gfs
		popitam->init_DIG(); // PREPARE LA DIGESTION
		
		
		// DIGESTION: dynamic initialization
		digest.SetCompare(popitam);
		// PEPTIDE RANGE: ABSOLUTE MIN = 666 (~6aa); ABSOLUTE MAX = 3333 (~30aa);
		double MIN = 666;
		double MAX = 3333;
		
		// c'est l'erreur sur la masse parente qui determine le range
		if (!runManParam->m_MUTMOD) {
			if ((spectrumData->get_parentMassM() - runManParam->PREC_MASS_ERROR) > 666) {  
				MIN = spectrumData->get_parentMassM() - runManParam->PREC_MASS_ERROR;
			}
			if ((spectrumData->get_parentMassM() + runManParam->PREC_MASS_ERROR) < 3333) { 
				MAX = spectrumData->get_parentMassM() + runManParam->PREC_MASS_ERROR;
			}
		}
		else {
			if ((spectrumData->get_parentMassM() - runManParam->UP_LIMIT_RANGE_PM)  > 666) {  
				MIN = spectrumData->get_parentMassM() - runManParam->UP_LIMIT_RANGE_PM;
			}
			if ((spectrumData->get_parentMassM() - runManParam->LOW_LIMIT_RANGE_PM) < 3333) { 
				MAX = spectrumData->get_parentMassM() - runManParam->LOW_LIMIT_RANGE_PM;
			}
		}
		
		digest.Limit(MIN, MAX);
		// ---------------------------

		//gfs
		double dt1 = ((double)(clock()-t1)/(CLOCKS_PER_SEC/1000));
		unsigned long int t2 = clock();
		//eof gfs
		popitam->Run(&digest);      // IDENTIFIE LE SPECTRE
		//gfs
		double dt2 = ((double)(clock()-t2)/(CLOCKS_PER_SEC/1000));
		//cout << "init_POP = " << dt0 << endl;
		//cout << "init_DIG = " << dt1 << endl;
		//cout << "Run = " << dt2 << endl;
		//eof gfs
		
		popitam->EndRun(spectrumData->specID);
		
		fprintf(runManParam->FILEOUT,	"\nProcessing time was:	%f\n", (double)(clock()-iniTime)/CLOCKS_PER_SEC);
		
		//popitam->DisplayUnusedAC(runManParam->FILEOUT);
		fprintf(runManParam->FILEOUT,	"\n\nNEXT______________________________________________________________\n\n");
		
		if (popitam != NULL) {
			delete popitam;
			popitam = NULL;
			memCheck.popitam--;
		}
	}

	if (runManParam->XML_OUT) {
		fprintf(runManParam->FILEOUTXML, "</spectrumMatchList>\n");
		fprintf(runManParam->FILEOUTXML, "<spectrumList>\n");
	}

	if (spectrumData != NULL) {
		delete spectrumData;
		spectrumData = NULL;
		memCheck.data--;
	}

	if (runManParam->XML_OUT) {
		// je reload les spectres pour le fichier output xml (les spectres doivent appara�tre � la fin)
		runManParam->FILEIN.Close();
		runManParam->FILEIN.Open(runManParam->FILEINNAME, "r");
		spectrumData = new data();
		memCheck.data++;
		spectrumData->init(runManParam);
		
		while(spectrumData->load()) {
			spectrumData->writeSpectrumListXML(runManParam->FILEOUTXML);
		}
		
		if (spectrumData != NULL) {
			delete spectrumData;
			spectrumData = NULL;
			memCheck.data--;
		}
		
		fprintf(runManParam->FILEOUTXML, "</spectrumList>\n");
	}
}