Skip to content

Secret bytes over remoting#1014

Merged
jtnord merged 2 commits intojenkinsci:masterfrom
jtnord:secretBytes-remoting
Feb 6, 2026
Merged

Secret bytes over remoting#1014
jtnord merged 2 commits intojenkinsci:masterfrom
jtnord:secretBytes-remoting

Conversation

@jtnord
Copy link
Member

@jtnord jtnord commented Feb 1, 2026

Any attempt to serialize SecretBytes over a remoting channel was doomed to failure as the remote side would have a different CredentialsConfidentialKey leading to either a failure to decrypt or garbage data.

This change fixes this by transferring the data in plan text and re-encrypting on the receiving side (if and only if serialisation is being performed over a remoting channel)

Testing done

Introduced new unit test, that fails before the fix and passes after the fix, existing unit tests still pass

fixes: #1013

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests that demonstrate the feature works or the issue is fixed

If we tried to transfer SecretBytes via Remoting then the remote side
would end up with the encrypted byte[] but not the key needed to decrypt
the data.

Sending the decryption key would be a bad thing, but we can send the
data in plain text to the agent and then re-encrypt it with the remoting
(agent) sides key.  As generally the remoting side would not be a
Jenkins the mock encryption key would be used in this case.

Whilst the mock key is static, it is not expected that ian agent
persists these SecretBytes.

fixes: jenkinsci#1013
@jtnord jtnord force-pushed the secretBytes-remoting branch from 95622b3 to 1d420ac Compare February 1, 2026 12:31
@jtnord jtnord marked this pull request as ready for review February 1, 2026 12:42
@jtnord jtnord requested a review from a team as a code owner February 1, 2026 12:42
@jtnord jtnord marked this pull request as draft February 1, 2026 12:42

@Override
public Void call() throws AssertionError {
assertThat(sb.getPlainData(), is(expectedUnencryptedValue));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prior to the fix this errored with

java.io.IOException: Remote call on slave0 failed
	at hudson.remoting.Channel.call(Channel.java:1112)
	at com.cloudbees.plugins.credentials.SecretBytesTest.serialisationOverRemoting(SecretBytesTest.java:176)
Caused by: java.lang.Error: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
	at app//com.cloudbees.plugins.credentials.SecretBytes.getPlainData(SecretBytes.java:141)
	at app//com.cloudbees.plugins.credentials.SecretBytesTest$CheckSecretBytesCallable.call(SecretBytesTest.java:191)
	at app//com.cloudbees.plugins.credentials.SecretBytesTest$CheckSecretBytesCallable.call(SecretBytesTest.java:179)
	at hudson.remoting.UserRequest.perform(UserRequest.java:225)
	at hudson.remoting.UserRequest.perform(UserRequest.java:50)
	at hudson.remoting.Request$2.run(Request.java:391)
	at hudson.remoting.InterceptingExecutorService.lambda$wrap$0(InterceptingExecutorService.java:81)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
	Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to slave0
		at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1916)
		at hudson.remoting.UserRequest$ExceptionResponse.retrieve(UserRequest.java:384)
		at hudson.remoting.Channel.call(Channel.java:1108)
		at com.cloudbees.plugins.credentials.SecretBytesTest.serialisationOverRemoting(SecretBytesTest.java:176)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
	at java.base/com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:861)
	at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:941)
	at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:734)
	at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
	at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2244)
	at app//com.cloudbees.plugins.credentials.SecretBytes.getPlainData(SecretBytes.java:139)
	... 10 more

@jimklimov
Copy link
Contributor

jimklimov commented Feb 6, 2026

For posterity and cross-linking: this PR and some earlier landed commits may borrow from work started and stalled in #391 and altogether this should finally solve issue https://issues.jenkins.io/browse/JENKINS-70101 and https://issues.jenkins.io/browse/JENKINS-67778 (#913)

@jtnord jtnord marked this pull request as ready for review February 6, 2026 18:02
@jtnord jtnord added the bug label Feb 6, 2026
@jtnord jtnord changed the title Secret bytes remoting Secret bytes over remoting Feb 6, 2026
@jtnord jtnord merged commit ad001ed into jenkinsci:master Feb 6, 2026
19 checks passed
@jtnord jtnord deleted the secretBytes-remoting branch February 6, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SecretBytes can not be transferred via Remoting

2 participants