package jenkins.security; import hudson.scm.SCM; import hudson.tasks.Builder; import hudson.util.Secret; import javax.annotation.CheckForNull; import java.io.IOException; /** * Confidential information that gets stored as a singleton in Jenkins, mostly some random token value. * * <p> * The actual value is persisted via {@link ConfidentialStore}, but each use case that requires * a secret like this should use a separate {@link ConfidentialKey} instance so that one compromised * {@link ConfidentialKey} (say through incorrect usage and failure to protect it) shouldn't compromise * all the others. * * <p> * {@link ConfidentialKey} is ultimately a sequence of bytes, * but for convenience, a family of subclasses are provided to represent the secret in different formats. * See {@link HexStringConfidentialKey} and {@link HMACConfidentialKey} for example. In addition to the programming * ease, these use case specific subtypes make it harder for vulnerability to creep in by making it harder * for the secret to leak. * * <p> * The {@link ConfidentialKey} subtypes are expected to be used as a singleton, like {@link JnlpSlaveAgentProtocol#SLAVE_SECRET}. * For code that relies on XStream for persistence (such as {@link Builder}s, {@link SCM}s, and other fragment objects * around builds and jobs), {@link Secret} provides more convenient way of storing secrets. * * @author Kohsuke Kawaguchi * @see Secret * @since 1.498 */ public abstract class ConfidentialKey { /** * Name of the key. This is used as the file name. */ private final String id; protected ConfidentialKey(String id) { this.id = id; } protected @CheckForNull byte[] load() throws IOException { return ConfidentialStore.get().load(this); } protected void store(byte[] payload) throws IOException { ConfidentialStore.get().store(this,payload); } public String getId() { return id; } }