Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WFCORE-7033] Add support for signature validation in update/revert operations #23

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2024 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.wildfly.installationmanager;

/**
* Thrown when an operation failed due to a component being signed with an untrusted signature.
*/
public class MissingSignatureException extends Exception {
private String description;

public MissingSignatureException(String message, Throwable cause, String description) {
super(message, cause);
this.description = description;
}

/**
* identifier of the missing certificate.
*
* @return
*/
public String getDescription() {
return description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2024 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.wildfly.installationmanager;

import java.util.Objects;

/**
* Certificate information used to validate the installation components
*/
public class TrustCertificate {
private final String keyID;
private final String fingerprint;
private final String description;
private final String status;

public TrustCertificate(String keyID, String fingerprint, String description, String status) {
this.keyID = keyID;
this.fingerprint = fingerprint;
this.description = description;
this.status = status;
}

/**
* hex form of the certificate key ID
* @return
*/
public String getKeyID() {
return keyID;
}

/**
* Hash of the certificate, used to verify integrity of the certificate.
*
* @return
*/
public String getFingerprint() {
return fingerprint;
}

/**
* Description of the certificate identity.
*
* @return
*/
public String getDescription() {
return description;
}

/**
* trust status of the certificate in the installation
* @return
*/
public String getStatus() {
return status;
}

@Override
public String toString() {
return "TrustCertificate{" +
"keyID='" + keyID + '\'' +
", fingerprint='" + fingerprint + '\'' +
", description='" + description + '\'' +
", status='" + status + '\'' +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TrustCertificate that = (TrustCertificate) o;
return Objects.equals(keyID, that.keyID) && Objects.equals(fingerprint, that.fingerprint) && Objects.equals(description, that.description) && Objects.equals(status, that.status);
}

@Override
public int hashCode() {
return Objects.hash(keyID, fingerprint, description, status);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import org.wildfly.installationmanager.ManifestVersion;
import org.wildfly.installationmanager.OperationNotAvailableException;
import org.wildfly.installationmanager.Repository;
import org.wildfly.installationmanager.TrustCertificate;

import java.io.InputStream;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
Expand Down Expand Up @@ -56,8 +58,11 @@ public interface InstallationManager {
*
* @param revision hash of a revision record to be reverted to.
* @param candidatePath {@code Path} were the updated version of the server should be located.
* @param repositories List of repositories to be used to prepare this update.I f it is null or an empty list,
* @param repositories List of repositories to be used to prepare this update.If it is null or an empty list,
* the default repositories will be used instead.
* @throws org.wildfly.installationmanager.MissingSignatureException if the installation requires PGP checks
* and one of the components is signed with an
* unknown signature.
* @throws Exception In case of an error.
*/
void prepareRevert(String revision, Path candidatePath, List<Repository> repositories) throws Exception;
Expand All @@ -71,6 +76,9 @@ public interface InstallationManager {
* the default repositories will be used instead.
* @return true if the update candidate was generated, false if candidate was no generated due to not finding any pending updates
* @throws IllegalArgumentException if the Path is not writable.
* @throws org.wildfly.installationmanager.MissingSignatureException if the installation requires PGP checks
* and one of the components is signed with an
* unknown signature.
* @throws Exception In case of an error.
*/
boolean prepareUpdate(Path candidatePath, List<Repository> repositories) throws Exception;
Expand Down Expand Up @@ -220,4 +228,49 @@ public interface InstallationManager {
* @throws Exception - if there was an exception accessing the server information or if the candidate is invalid
*/
Collection<FileConflict> verifyCandidate(Path candidatePath, CandidateType candidateType) throws Exception;

/**
* adds the {@code certificate} to the installation's trusted certificates list and makes it available to verify installation
* components.
*
* @param certificate
* @throws Exception
*/
void acceptTrustedCertificates(InputStream certificate) throws Exception;

/**
* remove the certificate identified by the {@code keyID} from the list of certificates trusted to verify installation
* components.
*
* @param keyID - hex form of the keyID
* @throws Exception
*/
void revokeTrustedCertificate(String keyID) throws Exception;

/**
* list certificates trusted by the installation to verify components.
*
* @return
* @throws Exception
*/
Collection<TrustCertificate> listTrustedCertificates() throws Exception;

/**
* download the certificate and parse it.
*
* @param cert - the input stream or armour-protected GPG certificate
* @return - certificate information
* @throws Exception - if unable to download the certificate or parse it.
*/
TrustCertificate parseCertificate(InputStream cert) throws Exception;

/**
* attempts to download the certificates required to install components from the configured channels.
* Note this method will only download certificates defined in the installation's channel definition. If the
* components in the channel are signed with other signatures, those will not be resolved.
*
* @return - input streams of downloaded required certificates.
* @throws Exception - if unable to download the certificate.
*/
Collection<InputStream> downloadRequiredCertificates() throws Exception;
}
Loading