package jenkins.security;
import hudson.Util;
import java.io.IOException;
/**
* {@link ConfidentialKey} that is the random hexadecimal string of length N.
*
* <p>
* This is typically used as a unique ID, as a hex dump is suitable for printing, copy-pasting,
* as well as use as an identifier.
*
* @author Kohsuke Kawaguchi
* @since 1.498
*/
public class HexStringConfidentialKey extends ConfidentialKey {
private final int length;
private volatile String secret;
/**
* @param length
* Length of the hexadecimal string.
*/
public HexStringConfidentialKey(String id, int length) {
super(id);
if (length%2!=0)
throw new IllegalArgumentException("length must be even: "+length);
this.length = length;
}
public HexStringConfidentialKey(Class owner, String shortName, int length) {
this(owner.getName()+'.'+shortName,length);
}
/**
* Returns the persisted hex string value.
*
* If the value isn't persisted, a new random value is created.
*
* @throws Error
* If the secret fails to load. Not throwing a checked exception is for the convenience
* of the caller.
*/
public String get() {
try {
if (secret==null) {
synchronized (this) {
if (secret==null) {
byte[] payload = load();
if (payload==null) {
payload = ConfidentialStore.get().randomBytes(length/2);
store(payload);
}
secret = Util.toHexString(payload).substring(0,length);
}
}
}
return secret;
} catch (IOException e) {
throw new Error("Failed to load the key: "+getId(),e);
}
}
}