All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.graylog2.cluster.certificates.CertificatesService Maven / Gradle / Ivy

There is a newer version: 6.1.4
Show newest version
/*
 * Copyright (C) 2020 Graylog, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Server Side Public License, version 1,
 * as published by MongoDB, Inc.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * Server Side Public License for more details.
 *
 * You should have received a copy of the Server Side Public License
 * along with this program. If not, see
 * .
 */
package org.graylog2.cluster.certificates;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
import org.graylog.security.certutil.keystore.storage.location.KeystoreMongoCollection;
import org.graylog.security.certutil.keystore.storage.location.KeystoreMongoCollections;
import org.graylog.security.certutil.keystore.storage.location.KeystoreMongoLocation;
import org.graylog2.database.MongoConnection;
import org.graylog2.security.encryption.EncryptedValue;
import org.graylog2.security.encryption.EncryptedValueService;

import javax.inject.Inject;
import java.util.Optional;

import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Indexes.ascending;
import static com.mongodb.client.model.Updates.combine;
import static com.mongodb.client.model.Updates.set;


public class CertificatesService {

    private static final String ENCRYPTED_VALUE_SUBFIELD = "encrypted_value";
    private static final String SALT_SUBFIELD = "salt";

    private final MongoDatabase mongoDatabase;
    private final EncryptedValueService encryptionService;

    @Inject
    public CertificatesService(final MongoConnection mongoConnection,
                               final EncryptedValueService encryptionService) {

        this.mongoDatabase = mongoConnection.getMongoDatabase();
        this.encryptionService = encryptionService;
        KeystoreMongoCollections.ALL_KEYSTORE_COLLECTIONS.forEach(collection -> {
            final MongoCollection dbCollection = mongoDatabase
                    .getCollection(collection.collectionName());
            dbCollection.createIndex(
                    ascending(collection.identifierField()),
                    new IndexOptions().unique(true));
        });


    }

    public boolean writeCert(final KeystoreMongoLocation keystoreMongoLocation,
                             final String cert) {
        final KeystoreMongoCollection collection = keystoreMongoLocation.collection();
        MongoCollection dbCollection = mongoDatabase.getCollection(collection.collectionName());
        final EncryptedValue encrypted = encryptionService.encrypt(cert);
        final UpdateResult result = dbCollection.updateOne(
                eq(collection.identifierField(), keystoreMongoLocation.nodeId()),
                combine(
                        set(collection.identifierField(), keystoreMongoLocation.nodeId()),
                        set(collection.encryptedCertificateField() + "." + ENCRYPTED_VALUE_SUBFIELD, encrypted.value()),
                        set(collection.encryptedCertificateField() + "." + SALT_SUBFIELD, encrypted.salt())
                ),
                new UpdateOptions().upsert(true)
        );
        return result.getModifiedCount() > 0 || result.getUpsertedId() != null;
    }

    public boolean hasCert(final KeystoreMongoLocation keystoreMongoLocation) {
        final KeystoreMongoCollection collection = keystoreMongoLocation.collection();
        MongoCollection dbCollection = mongoDatabase.getCollection(collection.collectionName());
        final FindIterable objects = dbCollection.find(
                eq(
                        collection.identifierField(),
                        keystoreMongoLocation.nodeId()
                )
        );
        final Document nodeCertificate = objects.first();
        if (nodeCertificate != null) {
            final Document encryptedCertificateDocument = nodeCertificate.get(collection.encryptedCertificateField(), Document.class);
            if (encryptedCertificateDocument != null) {
                return true;
            }
        }
        return false;
    }

    public Optional readCert(final KeystoreMongoLocation keystoreMongoLocation) {
        final KeystoreMongoCollection collection = keystoreMongoLocation.collection();
        MongoCollection dbCollection = mongoDatabase.getCollection(collection.collectionName());
        final FindIterable objects = dbCollection.find(
                eq(
                        collection.identifierField(),
                        keystoreMongoLocation.nodeId()
                )
        );
        final Document nodeCertificate = objects.first();

        if (nodeCertificate != null) {
            final Document encryptedCertificateDocument = nodeCertificate.get(collection.encryptedCertificateField(), Document.class);
            if (encryptedCertificateDocument != null) {
                final EncryptedValue encryptedCertificate = EncryptedValue.builder()
                        .value(encryptedCertificateDocument.getString(ENCRYPTED_VALUE_SUBFIELD))
                        .salt(encryptedCertificateDocument.getString(SALT_SUBFIELD))
                        .isDeleteValue(false)
                        .isKeepValue(false)
                        .build();

                return Optional.ofNullable(encryptionService.decrypt(encryptedCertificate));
            }
        }
        return Optional.empty();
    }

    public boolean removeCert(final KeystoreMongoLocation keystoreMongoLocation) {
        final KeystoreMongoCollection collection = keystoreMongoLocation.collection();
        MongoCollection dbCollection = mongoDatabase.getCollection(collection.collectionName());
        var result = dbCollection.deleteOne(
                eq(
                        collection.identifierField(),
                        keystoreMongoLocation.nodeId()
                )
        );
        return result.getDeletedCount() > 0;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy