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

Update to bouncycastle jdk18on with version 1.78.1 #785

Open
wants to merge 3 commits into
base: master
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
11 changes: 8 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,14 @@
<version>1.10</version>
</dependency>
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<version>140</version>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.78.1</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>1.78.1</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
Expand Down
20 changes: 15 additions & 5 deletions src/main/java/io/jenkins/update_center/Signer.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package io.jenkins.update_center;

import io.jenkins.update_center.json.JsonSignature;

import io.jenkins.update_center.util.Environment;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.TeeOutputStream;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.jvnet.hudson.crypto.CertificateUtil;
import org.jvnet.hudson.crypto.SignatureOutputStream;
import org.kohsuke.args4j.Option;
Expand All @@ -23,7 +25,6 @@
import java.nio.file.Files;
import java.security.DigestOutputStream;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Signature;
Expand Down Expand Up @@ -86,8 +87,17 @@ public JsonSignature sign(String json) throws GeneralSecurityException, IOExcept
X509Certificate signer = certs.get(0); // the first one is the signer, and the rest is the chain to a root CA.

PrivateKey key;
try (PEMReader pem = new PEMReader(Files.newBufferedReader(privateKey.toPath(), StandardCharsets.UTF_8))) {
key = ((KeyPair) pem.readObject()).getPrivate();
try (PEMParser pem = new PEMParser(Files.newBufferedReader(privateKey.toPath(), StandardCharsets.UTF_8))) {
final Object o = pem.readObject();
if (o instanceof PrivateKeyInfo) {
final PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) o;
key = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo);
} else if (o instanceof PEMKeyPair) {
final PEMKeyPair pemKeyPair = (PEMKeyPair) o;
key = new JcaPEMKeyConverter().getKeyPair(pemKeyPair).getPrivate();
} else {
throw new IllegalArgumentException("Unexpected type for private key: " + o.getClass().getName());
}
}

// the correct signature (since Jenkins 1.433); no longer generate wrong signatures for older releases.
Expand Down
65 changes: 65 additions & 0 deletions src/test/java/io/jenkins/update_center/SignerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.jenkins.update_center;

import io.jenkins.update_center.json.JsonSignature;
import java.nio.file.StandardCopyOption;
import java.util.Collections;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

// The resources used in these tests expire in 2034.
// Generated with:
// OpenSSL 3.3.2 3 Sep 2024 (Library: OpenSSL 3.3.2 3 Sep 2024)
// Using:
// openssl genrsa [-traditional] -out FILENAME.key 4096
// openssl req -new -x509 -days 3650 -key FILENAME.key -out FILENAME.cert -subj "/C=/ST=/L=/O=SignerTest/OU=SignerTest/CN=SignerTest/[email protected]"
public class SignerTest {
@Test
public void traditionalFormat() throws IOException, GeneralSecurityException {
Signer signer = new Signer();
try (InputStream is = SignerTest.class.getResourceAsStream("/traditional.key")) {
final Path filePath = Files.createTempFile("update-center2-", ".key");
Files.copy(is, filePath, StandardCopyOption.REPLACE_EXISTING);
signer.privateKey = filePath.toFile();
}
try (InputStream is = SignerTest.class.getResourceAsStream("/traditional.cert")) {
final Path filePath = Files.createTempFile("update-center2-", ".cert");
Files.copy(is, filePath, StandardCopyOption.REPLACE_EXISTING);
signer.certificates = Collections.singletonList(filePath.toFile());
}

final JsonSignature signature = signer.sign("{}");
assertThat(signature.getSignature512(), notNullValue());
assertThat(signature.getDigest512(), notNullValue());
assertThat(signature.getSignature(), notNullValue());
assertThat(signature.getCertificates().size(), is(1));
}

@Test
public void modernFormat() throws IOException, GeneralSecurityException {
Signer signer = new Signer();
try (InputStream is = SignerTest.class.getResourceAsStream("/modern.key")) {
final Path filePath = Files.createTempFile("update-center2-", ".key");
Files.copy(is, filePath, StandardCopyOption.REPLACE_EXISTING);
signer.privateKey = filePath.toFile();
}
try (InputStream is = SignerTest.class.getResourceAsStream("/modern.cert")) {
final Path filePath = Files.createTempFile("update-center2-", ".cert");
Files.copy(is, filePath, StandardCopyOption.REPLACE_EXISTING);
signer.certificates = Collections.singletonList(filePath.toFile());
}

final JsonSignature signature = signer.sign("{}");
assertThat(signature.getSignature512(), notNullValue());
assertThat(signature.getDigest512(), notNullValue());
assertThat(signature.getSignature(), notNullValue());
assertThat(signature.getCertificates().size(), is(1));
}
}
33 changes: 33 additions & 0 deletions src/test/resources/modern.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFrzCCA5egAwIBAgIUTTROuI9hnRw1B+dRBsEr7Uv7VaYwDQYJKoZIhvcNAQEL
BQAwZzETMBEGA1UECgwKU2lnbmVyVGVzdDETMBEGA1UECwwKU2lnbmVyVGVzdDET
MBEGA1UEAwwKU2lnbmVyVGVzdDEmMCQGCSqGSIb3DQEJARYXZXhhbXBsZUBleGFt
cGxlLmludmFsaWQwHhcNMjQxMDIyMjAxNDI0WhcNMzQxMDIwMjAxNDI0WjBnMRMw
EQYDVQQKDApTaWduZXJUZXN0MRMwEQYDVQQLDApTaWduZXJUZXN0MRMwEQYDVQQD
DApTaWduZXJUZXN0MSYwJAYJKoZIhvcNAQkBFhdleGFtcGxlQGV4YW1wbGUuaW52
YWxpZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK/ldRUn1LAFAYqc
JxB6MOwvTCEoUMfQvT4EFgVRMhVCtriDHWv6Gyli6C2NKvQj3/+SbLCbCE6VzjR8
x4s7afuz/7tR7rX7EXUX9MgB1Tq4apvUKrMD1qWK4bJk7m0naw+xCN6PryiHXd54
N9E3kt/7O/ei5A3yhL9wWvT5Vbe+IlmScD/UEVPCtmxju8oIJQkXgE8NXnkvn6Bc
iUwaCuSffRuedFqOWAPgF4hNkowg8N3JjKtu3R9S5lLcaGyFA1OeN7flHZB429o2
vDLdD4qlRkE+QaweXI2zPnviCdWOA0E/qn6TdrLrHqMBDVHy2FwrWW3Z3NmqmquE
XzpcmoF3/gEkHX3sAzprP5JLCv87AbTKYIFTXdKsjTnuP+fVAWPfkFOVcUHoWO3E
x79AWGUCPPiQfmiWHJsQlOYSyVqt8IhYh61hPXIOgtnCzw/HwvrDG9N3/XXyJS/b
9uOIOAli0hamwgJMIhLYwGEPemb6nhNiBDovWMLbZozxxNVFfCjSj7jAVlVHu4cj
M7korupX7GtleMt8csGiatCD7IbH8MaS2szOLtBrlmLVmrkShmtnu3SvMw17XGRW
0ZG026OU2kebg8ZZJfd/xZdJzpqXubxXvEJsiR1MIEQS3yPAFFn30KSFg13tr6ZP
rPzL52LPCxNy3pMcCwwdwt6BUlXjAgMBAAGjUzBRMB0GA1UdDgQWBBS7Zj7qGtVj
pfbY/ggAxHXmEORDmDAfBgNVHSMEGDAWgBS7Zj7qGtVjpfbY/ggAxHXmEORDmDAP
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBZGx4SWxuxV33QlJXT
7mEAEueNJKr1B8psDYxJKHZGDlVnADT8zftyr35vQzs2SBaWtXU+4hUf/BMgkWxX
Fh6lZjhU+N5mTd5eVBB0YfYb73FwaJc9jbCTXsy4eDLpw+W7LUzw7twK7LKz8XIz
m6nHIDqfj6ts+QJ2sGa+dtcz1DChM3DOu4iD4Z8/KFYOhxS9JlaEzMqwbXRPmewm
ONHb0z5Xw57Kf0VrA/FxFg6DJHoJVENnekot3wPML/mhGxjfHcWBEcgVKYKtQvxm
KkClanrecA6Wdjw/5M4uaAQtCh4/tLOTg7msKrQ6PHQWrqkwTUCszqRfjjC4vGeT
TO3h24HX7ty/j/72Idwk9DeipOVgQg8/Ld5O1vf5WfudnH7qy6bNDRoYEwSbqpAy
IhZxt9nEiYievlvA9lB/cD/owYU27m1ON9XmbTHHckTQZ4X8FNXfsmjtD6auw7x2
kVbwDIqwOQVxWWPlS0Hto9J3ArVyuH1xXLMq7eZTZDWWuJ3BwnRPjK2OQA4NEqRs
EEJInIi8wPRQLCW78SSJBCsgav5G8jIUl7JFrrn5DOPAysTf5KhC4CNrkZB39be/
fRo8BjLbmB9Xo6jmqrhZNlh1yJVmrx9/T7FaQnjK1jgpnVzyhlqPHhmxZH/ROSXu
BvsbQAUNn0tnXAeAYyOhM0/Fgg==
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions src/test/resources/modern.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
6y3uXEUymPA0CSxXU7B7EY/M9RBtrQ==
-----END PRIVATE KEY-----
33 changes: 33 additions & 0 deletions src/test/resources/traditional.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFrzCCA5egAwIBAgIUFlHQajUKm7A1u0dwJR4PonJL0lswDQYJKoZIhvcNAQEL
BQAwZzETMBEGA1UECgwKU2lnbmVyVGVzdDETMBEGA1UECwwKU2lnbmVyVGVzdDET
MBEGA1UEAwwKU2lnbmVyVGVzdDEmMCQGCSqGSIb3DQEJARYXZXhhbXBsZUBleGFt
cGxlLmludmFsaWQwHhcNMjQxMDIyMjAwNTI3WhcNMzQxMDIwMjAwNTI3WjBnMRMw
EQYDVQQKDApTaWduZXJUZXN0MRMwEQYDVQQLDApTaWduZXJUZXN0MRMwEQYDVQQD
DApTaWduZXJUZXN0MSYwJAYJKoZIhvcNAQkBFhdleGFtcGxlQGV4YW1wbGUuaW52
YWxpZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK+/Xwh1TKhBCcJ8
e6gWKFrCBqeW4HWxzNpXEn7sCpl9IrBb/1p5+s0WFvdKuCVjrh86qgAxli/58MI5
bofgfZah09PHTE4F7nRW4gTCI70H1wonUMZ7RmmIW/Eomi78qqbM7cvWjdIHyNAO
13v7sYpr9VRIT0NdteY0vKaM2JOtjvL5PrfpeC4ItPNijxxHBRM53H15iwv6aMIe
dGZwb1sZbALQOwtZRami2d1g1cip8+fvii0B7zOpHl9RSQnIykXFPr1G0P+GiwSn
0jM49zIZivPYM7Oi8njHVDTKmt4RgqioA0nJhw1lh+GSw6EYMhLzIv5qUEWwGhw9
FYEEUMhfLtzzMzkDinkok13FV8sRxRRANU39ukbWSromL8o8AYe0u8tZ13otXAgE
WXbMTasTbZxDCIxFamXW4GavamdtUxdycj3sDylf/gJWlJ9Dhjw4B2/aN/LxU9U8
FCSdLGJ5Jr/VOyopV8OmOwcLVGGHMU8Wjos3/PiAxSLtMzOErrvPJDmIYQ50BE9O
QeU7UYNn8D++6xYDQI4ApuHVYIusoH18MjNslxPOHi4ucTK4FDVpW+jWGYXkk69T
blEumLmkYyEvOJUIiy6QG9KsZ8rCoVtcfqxccKzZAux6RehymyChEVD4hlPz+Le8
WMkuuYVeaxHyS47jUJB/rnvrUFWvAgMBAAGjUzBRMB0GA1UdDgQWBBT254kvHtxf
PHdwENknZiUJBd1eNTAfBgNVHSMEGDAWgBT254kvHtxfPHdwENknZiUJBd1eNTAP
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAfgM/c5YdgeX+9M5N1
+oW8JcPqwkpT+F9l4vK0J75tMryiqGkqJtgmgqY3SGQPwgML0LgCdRDB1c740a04
M72ronvkLRYg6pk3EAceulWpcC0GwwRPvtivBpnilfwl/B+QVp1Ur4TfkhDIKHui
d1mvhVFCJ5U+gHJZdUnPBliXHnrBAMO4IcMVbNgr9O/EA5wJvF7xW01qmnexD39D
BJWyplkja6gQDVuRoBV4xf3M0KgyVJJxswpCdHvk4D359WDX8APqb39bunOdKbfG
eNZi5JzzgNa6tUd6dC7pdIckwWkknvtKNmUhWmNnMgtXfsUORg9ytOw5JbQ/tXqK
R2kjosx2zkWcqjB4Exih2jGr0pww1WVrL/yNE9LErM5rhxlSDI7G8sNZ/diG0Amt
fxnT2auidescBu+Z7j/+mGhD4n70htvyd/DAnDvkFOrbzre4PGlYwdq3Aye0YUNZ
U1oOmtxMsrc5eXXqZgbCG6UZJXaxufk5CWeiswzMYEJf5B9x25JXP6Km/DfRKgcn
iilDG896li0a/Awv6yRRT44kFZaYmGPxGK1T2rd0J5YZZdnwmOkj8QFbI2bZHrgp
4sC82EPUQyLA+3LuKL+7a7lgxGfQ/P0A3GXsmyxzOGstSs55gSFi78grxWO5r+Ay
B/Rl5ajepb8AoJQDiFkhxtA/bQ==
-----END CERTIFICATE-----
51 changes: 51 additions & 0 deletions src/test/resources/traditional.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----