bool
TLSTicketKeyManager::setTLSTicketKeySeeds(
    const std::vector<std::string>& oldSeeds,
    const std::vector<std::string>& currentSeeds,
    const std::vector<std::string>& newSeeds) {

  recordTlsTicketRotation(oldSeeds, currentSeeds, newSeeds);

  bool result = true;

  activeKeys_.clear();
  ticketKeys_.clear();
  ticketSeeds_.clear();
  const std::vector<string> *seedList = &oldSeeds;
  for (uint32_t i = 0; i < 3; i++) {
    TLSTicketSeedType type = (TLSTicketSeedType)i;
    if (type == SEED_CURRENT) {
      seedList = &currentSeeds;
    } else if (type == SEED_NEW) {
      seedList = &newSeeds;
    }

    for (const auto& seedInput: *seedList) {
      TLSTicketSeed* seed = insertSeed(seedInput, type);
      if (seed == nullptr) {
        result = false;
        continue;
      }
      insertNewKey(seed, 1, nullptr);
    }
  }
  if (!result) {
    VLOG(2) << "One or more seeds failed to decode";
  }

  if (ticketKeys_.size() == 0 || activeKeys_.size() == 0) {
    LOG(WARNING) << "No keys configured, falling back to default";
    SSL_CTX_set_tlsext_ticket_key_cb(ctx_->getSSLCtx(), nullptr);
    return false;
  }
  SSL_CTX_set_tlsext_ticket_key_cb(ctx_->getSSLCtx(),
                                   TLSTicketKeyManager::callback);

  return true;
}
Beispiel #2
0
Status KeyGenerator::generateNewKeysIfNeeded(OperationContext* opCtx) {

    if (MONGO_FAIL_POINT(disableKeyGeneration)) {
        return {ErrorCodes::FailPointEnabled, "key generation disabled"};
    }

    auto currentTime = LogicalClock::get(opCtx)->getClusterTime();
    auto keyStatus = _client->getNewKeys(opCtx, _purpose, currentTime);

    if (!keyStatus.isOK()) {
        return keyStatus.getStatus();
    }

    const auto& newKeys = keyStatus.getValue();
    auto keyIter = newKeys.cbegin();

    LogicalTime currentKeyExpiresAt;

    long long keyId = currentTime.asTimestamp().asLL();

    if (keyIter == newKeys.cend()) {
        currentKeyExpiresAt = addSeconds(currentTime, _keyValidForInterval);
        auto status = insertNewKey(opCtx, _client, keyId, _purpose, currentKeyExpiresAt);

        if (!status.isOK()) {
            return status;
        }

        keyId++;
    } else if (keyIter->getExpiresAt() < currentTime) {
        currentKeyExpiresAt = addSeconds(currentTime, _keyValidForInterval);
        auto status = insertNewKey(opCtx, _client, keyId, _purpose, currentKeyExpiresAt);

        if (!status.isOK()) {
            return status;
        }

        keyId++;
        ++keyIter;
    } else {
        currentKeyExpiresAt = keyIter->getExpiresAt();
        ++keyIter;
    }

    // Create a new key in advance if we don't have a key on standby after the current one
    // expires.
    // Note: Convert this block into a loop if more reserved keys are desired.
    if (keyIter == newKeys.cend()) {
        auto reserveKeyExpiresAt = addSeconds(currentKeyExpiresAt, _keyValidForInterval);
        auto status = insertNewKey(opCtx, _client, keyId, _purpose, reserveKeyExpiresAt);

        if (!status.isOK()) {
            return status;
        }
    } else if (keyIter->getExpiresAt() < currentTime) {
        currentKeyExpiresAt = addSeconds(currentKeyExpiresAt, _keyValidForInterval);
        auto status = insertNewKey(opCtx, _client, keyId, _purpose, currentKeyExpiresAt);

        if (!status.isOK()) {
            return status;
        }
    }

    return Status::OK();
}