This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch 3.6.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/3.6.x-fixes by this push:
new 7dfbeb85774 Fix bug in JwsInputStream and add tests (#3404)
7dfbeb85774 is described below
commit 7dfbeb8577460571e8bec0f7cca7b19aa8beaa1e
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Thu Aug 27 14:18:22 2026 +0100
Fix bug in JwsInputStream and add tests (#3404)
(cherry picked from commit a83656f4fe7d334707e752a790aecfb6ac78baf9)
---
.../cxf/rs/security/jose/jws/JwsInputStream.java | 3 +-
.../rs/security/jose/jws/JwsInputStreamTest.java | 82 ++++++++++++++++++++++
2 files changed, 83 insertions(+), 2 deletions(-)
diff --git
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsInputStream.java
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsInputStream.java
index 6225e35c834..53662ebba2b 100644
---
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsInputStream.java
+++
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsInputStream.java
@@ -21,7 +21,6 @@ package org.apache.cxf.rs.security.jose.jws;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.nio.ByteBuffer;
public class JwsInputStream extends FilterInputStream {
private final JwsVerificationSignature signature;
@@ -42,7 +41,7 @@ public class JwsInputStream extends FilterInputStream {
public int read() throws IOException {
int value = super.read();
if (value != -1) {
- byte[] bytes = ByteBuffer.allocate(Integer.SIZE /
8).putInt(value).array();
+ byte[] bytes = new byte[] {(byte)value};
signature.update(bytes, 0, bytes.length);
} else {
verify();
diff --git
a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsInputStreamTest.java
b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsInputStreamTest.java
new file mode 100644
index 00000000000..53581dafdb4
--- /dev/null
+++
b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsInputStreamTest.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
+
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class JwsInputStreamTest {
+
+ private static final byte[] KEY =
"0123456789abcdef0123456789abcdef".getBytes(StandardCharsets.UTF_8);
+ private static final byte[] CONTENT = "signed multipart
content".getBytes(StandardCharsets.UTF_8);
+
+ @Test
+ public void testSingleByteReadVerifiesValidSignature() throws Exception {
+ byte[] signatureBytes = sign(CONTENT);
+
+ JwsVerificationSignature vSig = createVerificationSignature();
+ try (JwsInputStream jwsStream =
+ new JwsInputStream(new ByteArrayInputStream(CONTENT), vSig,
signatureBytes, true)) {
+ // Reading one byte at a time must feed the exact content bytes
into the
+ // signature and thus accept a valid signature at the end of the
stream
+ while (jwsStream.read() != -1) {
+ // consume
+ }
+ }
+ }
+
+ @Test
+ public void testTamperedContentIsRejected() throws Exception {
+ byte[] signatureBytes = sign(CONTENT);
+
+ byte[] tampered = CONTENT.clone();
+ tampered[0] ^= 0x01;
+ JwsVerificationSignature vSig = createVerificationSignature();
+ try (JwsInputStream jwsStream =
+ new JwsInputStream(new ByteArrayInputStream(tampered), vSig,
signatureBytes, true)) {
+ byte[] buf = new byte[8];
+ try {
+ while (jwsStream.read(buf, 0, buf.length) != -1) {
+ // consume
+ }
+ fail("Failure expected on tampered content");
+ } catch (JwsException ex) {
+ // expected
+ }
+ }
+ }
+
+ private byte[] sign(byte[] content) {
+ HmacJwsSignatureProvider provider = new HmacJwsSignatureProvider(KEY,
SignatureAlgorithm.HS256);
+ JwsSignature sig = provider.createJwsSignature(new
JwsHeaders(SignatureAlgorithm.HS256));
+ sig.update(content, 0, content.length);
+ return sig.sign();
+ }
+
+ private JwsVerificationSignature createVerificationSignature() {
+ HmacJwsSignatureVerifier verifier = new HmacJwsSignatureVerifier(KEY,
SignatureAlgorithm.HS256);
+ return verifier.createJwsVerificationSignature(new
JwsHeaders(SignatureAlgorithm.HS256));
+ }
+}