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

Fix support for BCFIPS Security #114

Merged
merged 1 commit into from
Oct 3, 2024
Merged
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
12 changes: 11 additions & 1 deletion mina-sshd-api-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
<artifactId>bouncycastle-api</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-test-harness</artifactId>
<version>2270.v87a_0ea_b_54da_0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jenkins.test.fips</groupId>
<artifactId>fips-bundle-test</artifactId>
<version>23.v76d4fd57f5b_d</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* The MIT License
*
* Copyright (c) 2024, Olivier Lamy.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.jenkins.plugins.mina_sshd_api.core.bouncycastle_registar;

import hudson.Plugin;
import jenkins.security.FIPS140;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

import java.security.Security;
import java.util.logging.Logger;

/**
* In FIPS environment, Apache Mina needs to be tailored with a custom setup to enable FIPS mode
* and register BCFIPS as security provider
*
* This can be done via System properties but needs to be done BEFORE any Mina classes have been loaded
*/
@Restricted(NoExternalUse.class)
public class FIPSRegistarInitPlugin extends Plugin {

private static final Logger LOG = Logger.getLogger(FIPSRegistarInitPlugin.class.getName());
@Override
public void start() throws Exception {
if(FIPS140.useCompliantAlgorithms() && Security.getProvider("BCFIPS") != null) {
LOG.info("register enable FIPS mode for Apache Mina and register defaultProvider as BCFIPS");
System.setProperty("org.apache.sshd.security.fipsEnabled", "true");
System.setProperty("org.apache.sshd.security.defaultProvider", "BCFIPS");
} else {
LOG.config("not needed to register FIPSBouncyCastleSecurityProviderRegistar");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package io.jenkins.plugins.mina_sshd_api.core.bouncycastle_registar;

import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.RealJenkinsRule;

import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;

public class TestBCFIPSRegistar {

@Rule
public RealJenkinsRule j = new RealJenkinsRule().withFIPSEnabled()
.omitPlugins("eddsa-api").javaOptions("-Xmx256m");

@Test
public void BCFIPSRegistered() throws Throwable {

URI path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("rsa2048")).toURI();
j.then(r -> {
Iterable<KeyPair> keyPairs = SecurityUtils.loadKeyPairIdentities(null, null,
Files.newInputStream(Path.of(path)) , FilePasswordProvider.of("theaustraliancricketteamisthebest"));
assertThat(keyPairs.iterator().next(), notNullValue());
});
}

@Test
public void BCFIPSRegisteredRejectSSHkeyGen() throws Throwable {

URI path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("id_rsa-keygen-rsa-2048")).toURI();
j.then(r -> {
try {
Iterable<KeyPair> keyPairs = SecurityUtils.loadKeyPairIdentities(null, null,
Files.newInputStream(Path.of(path)), FilePasswordProvider.of("theaustraliancricketteamisthebest"));
keyPairs.iterator().next();
} catch (NoSuchAlgorithmException e) {
// all good
// we cannot use expected = NoSuchAlgorithmException.class
// as we get org.jvnet.hudson.test.RealJenkinsRule$StepException
}
});
}

@Test
public void BCFIPSRegisteredRejectSSHkeyGened25519() throws Throwable {

URI path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("ed25519.pem")).toURI();
j.then(r -> {
try {
Iterable<KeyPair> keyPairs = SecurityUtils.loadKeyPairIdentities(null, null,
Files.newInputStream(Path.of(path)), FilePasswordProvider.of(""));
keyPairs.iterator().next();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
// all good
// we cannot use expected = NoSuchAlgorithmException.class
// as we get org.jvnet.hudson.test.RealJenkinsRule$StepException
}
});
}

@Test
public void loadSSHkeyGen_ed25519() throws Throwable {
URI path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("ed25519.pem")).toURI();
Iterable<KeyPair> keyPairs = SecurityUtils.loadKeyPairIdentities(null, null,
Files.newInputStream(Path.of(path)), FilePasswordProvider.of(""));
assertThat(keyPairs.iterator().next(), notNullValue());
}

@Test
public void loadSSHkeyGen() throws Throwable {
URI path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("id_rsa-keygen-rsa-2048")).toURI();
Iterable<KeyPair> keyPairs = SecurityUtils.loadKeyPairIdentities(null, null,
Files.newInputStream(Path.of(path)), FilePasswordProvider.of("theaustraliancricketteamisthebest"));
assertThat(keyPairs.iterator().next(), notNullValue());

}

}
3 changes: 3 additions & 0 deletions mina-sshd-api-common/src/test/resources/ed25519.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIKZJkXaT3aQW9hmCefM7leOt/pXVAC5HAZTfw85tJGI+
-----END PRIVATE KEY-----
50 changes: 50 additions & 0 deletions mina-sshd-api-common/src/test/resources/id_rsa-keygen-rsa-2048
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
-----BEGIN OPENSSH PRIVATE KEY-----
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
Zb1gnNln2c/us1N2cIYRIssU8=
-----END OPENSSH PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDVjUbLFP9Qjj6WC2vomiQJBLhSFHO8+J0oauXRe6Z0ZtVC+jZgyy7bmQhOypblipTzR5H95QmimMPQL4EKbjpW/PsCp4kG8kRlbFkTk2fPm9LHmOcPUs5iWpDtm8ciF7V1/an1APNX0p9XZU/ieIWDbW8p2Kd9vNlLwlu10/3NT0/RTjBKEtxhdtbkXPJ0jO1JlpNa3Q946LyIw3K7DieaHoNedsnPdBcIl7c3TM2ymQh4fPpBXwIGEcWiuftkITLXQH0z2Buy9x5t0bybXS1BaAiOzbrPGHZC8sW1yK7gvWU3a8ahQNMGLzjo89ni4TrVny3o5N2t6L4kQ/9W76iUkAFreM5Nepofuw6w709e8EvyH8jIT7WuqdVtgpEVTqEc24fyNHVYbV0EJC+jFwqvYEG+rF8aKbWMaI6G4OA319Ikby/jN/fQnx7TDQnkwBHKAusq4yBfB6cCSqpWnJW5tQLD/Ux92jQ3WtJq4qAV4xqlHo3AalH15NmyMb8fB3kzjunxuuQmoln06HkWw2mANQi8BhS1lBvfV/dMC3UQuRa2sGnsUXHXE7y68YXSpJTk0gHSQbTi5ktFlLkgqaBI/4Zpuw4pZVKVqfJ/FKO57QRFlKGsaho9VqUxqwTml0iZrCj13tlLgnkg1stb5xv0x+jxJZFujsWCH5czzzcCtw== olamy@pop-os
30 changes: 30 additions & 0 deletions mina-sshd-api-common/src/test/resources/rsa2048
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFJDBWBgkqhkiG9w0BBQ0wSTAxBgkqhkiG9w0BBQwwJAQQOLc7iLj3g03uXcZp
lQ+k7wICCAAwDAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIFSRgLbfugPgEggTI
nSQ13Z0m3okyCMg6gPJkrsT7fgES3d61yg0F5EVIY2iIrUXnu7RhjbpXiAMj9arc
QNJaHVOH9OyNhMd/djFXvKB0xLK+l+OF9vzipqFqBAWdyzRLIEmEHzmrF8qBRcCt
bJOkTbtLYOpZYIk0UEY4XwrN1X6kZupWItVOZxHOdORBrYgfAXXAzs1QA4NKzW0u
c21t/f+iaTvpSgCnLa83Xc20vkbI0VvNLkapimojXJennAjxBV1pm5R80crA2/HH
w4r8MZ7aoMJ96H/V09lLN35D+wqx3LAmF07u3nHW0QmhdH5lY8spzOSeqAYC1dPM
vTI8kRQ9xpjMzHY2DyE/FSSUxcVzz8czbVN+QvRvlxP8AYoedpsYyagTWbrUs0Fq
lVswNSAqbLxxrteMEquSbAtjz0sl2lK15FD1V+4CNzc6jOpmmeMA3duFYXTg6vb+
ALxHHDtS1Y00b5gHnDPt3s/Uxpv6s4m7xvwZ3WztKaO9OC8rIanMK4lB+OxogPv9
ai/HXItR1reCWDDnRU7uXfOkXRlAOKSPhSK3vgsYfP8TVc5arlenFOmUwAuwHE1x
CCFg58EKVEgTNKRfupr/63819XM9l/3MqLSEiprMb+aACYEGWCulSWEcF2xq1AOE
uuvzhhXfuzYfSg/Qg7uZRb96M0/Or5sxRY4SUct8Ml/aHd3+2TZLEZGETBGXZi7E
O2MB8mO759NToFcG2wXvcPQ1zzIyj/en37yf1zuYQjEFzis2uNA/FNg3i2gdmbxR
XlEs/Ixe3HFsETJIlgWHHzC4HHtzEvzEKOvYd4qLyU8nQEMfNSk0YCUDyGYrmOub
u0Mq1UCgzVxoJxBqUiOtJkzzwCgxkjCGFfI781zS4juViAiIv12VG0hF5TRRZwPy
VvnH1i8vDkjFa2eXkA5/XYpO4euDN0DW77vOg6XRoPJewzmsvcykTfTj8H4XvtA9
BUxSEqd4Y++eMeQFLQ/CVrKmzAEhT2pYhWdlJ+y5PchHy5BE+HyjUxmWIVozvrBg
MXi538qFRykPZC60hDP66QFwYep2xlcDwpEdN5Wtsqur32GUzSvEV7Nl7NXouj5y
M9XiC38ze6+mgOQJqDWBcTQGZxI4AxBXTq3HPYsibFzWX8195+wJSYX/M9GaHrRN
brWuzCxAJJYZ5JMP0zY9eVQfz/BKg6V78vdKuQEm1R2+5j57tR4CkpTumYlaqGzp
L/m7LJC8ssQGMn23hoodcOGO760CXa3O5vA2zfr1jkUd56Rc0SRG8Mxgypv0JM5G
+BAmD71rbttdhNxBlfe9a3XTW0MJqSzoOKYoVMAnvyhdvSGtIZYGDM0WD0fTrK15
DbbvyWao74VFHPjVA0Fuo2vvdzLH+pZeXA19mYK7yMw5vsveroD7fk7Z05DYuHpb
pnO9vIFns3/PhBm7/IcBBgOX/b+tHLTd0jf+TeCrIn5hZXMz5AhjLpeVxux1O8Yd
wOajN9cywUZ/GuGhU1XxbkPieouIFgchS1MF92gmr6LX8T9kqEJfuAALceJ8FlwP
A7k878FhY9HinPMyNtw3G+wx1FdiqUXoP2dh7URFjTSjZPl2GDEnQO05HeJ+NBeD
3tJ10eVgpVEBaOF9Uru6LROnpZYjdyww
-----END ENCRYPTED PRIVATE KEY-----
17 changes: 17 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,23 @@
<artifactId>mina-sshd-api-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.16.1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Loading