feat:升级功能、密码卡框架、主密钥接口
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.cisd.tms.common.config;
|
||||
|
||||
import com.cisd.tms.common.config.properties.TmsCorsProperties;
|
||||
import com.cisd.tms.modules.auth.security.InternalAuthorizationInterceptor;
|
||||
import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
|
||||
import com.cisd.tms.security.openapi.OpenApiSignAuthInterceptor;
|
||||
import com.cisd.tms.common.util.TraceIdUtil;
|
||||
@@ -12,6 +14,7 @@ import org.slf4j.MDC;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@@ -19,14 +22,20 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
private final InternalApiAuthInterceptor internalApiAuthInterceptor;
|
||||
private final InternalAuthorizationInterceptor internalAuthorizationInterceptor;
|
||||
private final OpenApiSignAuthInterceptor openApiSignAuthInterceptor;
|
||||
private final TmsCorsProperties corsProperties;
|
||||
|
||||
public WebMvcConfig(
|
||||
InternalApiAuthInterceptor internalApiAuthInterceptor,
|
||||
OpenApiSignAuthInterceptor openApiSignAuthInterceptor
|
||||
InternalAuthorizationInterceptor internalAuthorizationInterceptor,
|
||||
OpenApiSignAuthInterceptor openApiSignAuthInterceptor,
|
||||
TmsCorsProperties corsProperties
|
||||
) {
|
||||
this.internalApiAuthInterceptor = internalApiAuthInterceptor;
|
||||
this.internalAuthorizationInterceptor = internalAuthorizationInterceptor;
|
||||
this.openApiSignAuthInterceptor = openApiSignAuthInterceptor;
|
||||
this.corsProperties = corsProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -56,10 +65,31 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
||||
.addPathPatterns("/api/**")
|
||||
.excludePathPatterns(
|
||||
"/api/v1/device/status",
|
||||
"/api/v1/auth/login"
|
||||
"/api/v1/auth/login",
|
||||
"/api/v1/auth/password-login",
|
||||
"/api/v1/auth/ukey-login",
|
||||
"/api/v1/auth/ukey-login/randoms"
|
||||
);
|
||||
|
||||
registry.addInterceptor(internalAuthorizationInterceptor)
|
||||
.addPathPatterns("/api/**");
|
||||
|
||||
registry.addInterceptor(openApiSignAuthInterceptor)
|
||||
.addPathPatterns("/openapi/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
if (!corsProperties.isEnabled() || corsProperties.getAllowedOriginPatterns().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns(corsProperties.getAllowedOriginPatterns().toArray(String[]::new))
|
||||
.allowedMethods(corsProperties.getAllowedMethods().toArray(String[]::new))
|
||||
.allowedHeaders(corsProperties.getAllowedHeaders().toArray(String[]::new))
|
||||
.exposedHeaders(corsProperties.getExposedHeaders().toArray(String[]::new))
|
||||
.allowCredentials(corsProperties.isAllowCredentials())
|
||||
.maxAge(corsProperties.getMaxAgeSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.cisd.tms.common.config.properties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "tms.web.cors")
|
||||
public class TmsCorsProperties {
|
||||
|
||||
private boolean enabled = true;
|
||||
private List<String> allowedOriginPatterns = new ArrayList<>(List.of(
|
||||
"http://localhost:*",
|
||||
"http://127.0.0.1:*"
|
||||
));
|
||||
private List<String> allowedMethods = new ArrayList<>(List.of(
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"OPTIONS"
|
||||
));
|
||||
private List<String> allowedHeaders = new ArrayList<>(List.of(
|
||||
"Authorization",
|
||||
"Content-Type",
|
||||
"X-Requested-With",
|
||||
"X-Internal-Token",
|
||||
"X-App-Id",
|
||||
"X-Timestamp",
|
||||
"X-Nonce",
|
||||
"X-Signature",
|
||||
"X-Trace-Id"
|
||||
));
|
||||
private List<String> exposedHeaders = new ArrayList<>(List.of(
|
||||
"X-Trace-Id"
|
||||
));
|
||||
private boolean allowCredentials = true;
|
||||
private long maxAgeSeconds = 3600;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public List<String> getAllowedOriginPatterns() {
|
||||
return allowedOriginPatterns;
|
||||
}
|
||||
|
||||
public void setAllowedOriginPatterns(List<String> allowedOriginPatterns) {
|
||||
this.allowedOriginPatterns = allowedOriginPatterns;
|
||||
}
|
||||
|
||||
public List<String> getAllowedMethods() {
|
||||
return allowedMethods;
|
||||
}
|
||||
|
||||
public void setAllowedMethods(List<String> allowedMethods) {
|
||||
this.allowedMethods = allowedMethods;
|
||||
}
|
||||
|
||||
public List<String> getAllowedHeaders() {
|
||||
return allowedHeaders;
|
||||
}
|
||||
|
||||
public void setAllowedHeaders(List<String> allowedHeaders) {
|
||||
this.allowedHeaders = allowedHeaders;
|
||||
}
|
||||
|
||||
public List<String> getExposedHeaders() {
|
||||
return exposedHeaders;
|
||||
}
|
||||
|
||||
public void setExposedHeaders(List<String> exposedHeaders) {
|
||||
this.exposedHeaders = exposedHeaders;
|
||||
}
|
||||
|
||||
public boolean isAllowCredentials() {
|
||||
return allowCredentials;
|
||||
}
|
||||
|
||||
public void setAllowCredentials(boolean allowCredentials) {
|
||||
this.allowCredentials = allowCredentials;
|
||||
}
|
||||
|
||||
public long getMaxAgeSeconds() {
|
||||
return maxAgeSeconds;
|
||||
}
|
||||
|
||||
public void setMaxAgeSeconds(long maxAgeSeconds) {
|
||||
this.maxAgeSeconds = maxAgeSeconds;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
public class TmsSecurityProperties {
|
||||
|
||||
private String internalToken = "change-me-internal-token";
|
||||
private final InternalAuth internalAuth = new InternalAuth();
|
||||
private final Openapi openapi = new Openapi();
|
||||
|
||||
public String getInternalToken() {
|
||||
@@ -18,10 +19,53 @@ public class TmsSecurityProperties {
|
||||
this.internalToken = internalToken;
|
||||
}
|
||||
|
||||
public InternalAuth getInternalAuth() {
|
||||
return internalAuth;
|
||||
}
|
||||
|
||||
public Openapi getOpenapi() {
|
||||
return openapi;
|
||||
}
|
||||
|
||||
public static class InternalAuth {
|
||||
private boolean enabled = true;
|
||||
private String debugRoleCode = "KEY_ADMIN";
|
||||
private String debugAuthLevel = "FULL";
|
||||
private String debugSessionToken = "DEBUG-BYPASS";
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getDebugRoleCode() {
|
||||
return debugRoleCode;
|
||||
}
|
||||
|
||||
public void setDebugRoleCode(String debugRoleCode) {
|
||||
this.debugRoleCode = debugRoleCode;
|
||||
}
|
||||
|
||||
public String getDebugAuthLevel() {
|
||||
return debugAuthLevel;
|
||||
}
|
||||
|
||||
public void setDebugAuthLevel(String debugAuthLevel) {
|
||||
this.debugAuthLevel = debugAuthLevel;
|
||||
}
|
||||
|
||||
public String getDebugSessionToken() {
|
||||
return debugSessionToken;
|
||||
}
|
||||
|
||||
public void setDebugSessionToken(String debugSessionToken) {
|
||||
this.debugSessionToken = debugSessionToken;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Openapi {
|
||||
private long timestampSkewSeconds = 300;
|
||||
private Map<String, String> clients = new HashMap<>();
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.sun.jna.Memory;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
@@ -33,6 +34,7 @@ public class PcieSessionTemplate {
|
||||
|
||||
private final Object lock = new Object();
|
||||
private volatile PcieNativeLibrary nativeLibrary;
|
||||
private volatile Pointer sharedDeviceHandle;
|
||||
|
||||
public PcieSessionTemplate(CryptoCardProperties properties, PcieErrorMapper errorMapper) {
|
||||
this.properties = properties;
|
||||
@@ -42,32 +44,22 @@ public class PcieSessionTemplate {
|
||||
public <T> T withDevice(String apiName, DeviceCallback<T> callback) {
|
||||
synchronized (lock) {
|
||||
PcieNativeLibrary lib = ensureLibraryLoaded();
|
||||
|
||||
PointerByReference deviceRef = new PointerByReference();
|
||||
int openRc = lib.SDF_OpenDevice(deviceRef);
|
||||
ensureSuccess(apiName + ":SDF_OpenDevice", openRc);
|
||||
|
||||
Pointer device = deviceRef.getValue();
|
||||
try {
|
||||
return callback.apply(lib, device);
|
||||
} finally {
|
||||
int closeRc = lib.SDF_CloseDevice(device);
|
||||
if (closeRc != 0) {
|
||||
log.warn("{} close device failed: {}", apiName, errorMapper.toMessage(closeRc));
|
||||
}
|
||||
}
|
||||
Pointer device = ensureSharedDeviceOpened(apiName, lib);
|
||||
return callback.apply(lib, device);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T withSession(String apiName, SessionCallback<T> callback) {
|
||||
return withDevice(apiName, (lib, deviceHandle) -> {
|
||||
PointerByReference sessionRef = new PointerByReference();
|
||||
Pointer ph = new Memory(8L);
|
||||
sessionRef.setValue(ph);
|
||||
int openSessionRc = lib.SDF_OpenSession(deviceHandle, sessionRef);
|
||||
ensureSuccess(apiName + ":SDF_OpenSession", openSessionRc);
|
||||
synchronized (lock) {
|
||||
PcieNativeLibrary lib = ensureLibraryLoaded();
|
||||
Pointer deviceHandle = ensureSharedDeviceOpened(apiName, lib);
|
||||
Pointer session = tryOpenSession(apiName, lib, deviceHandle);
|
||||
if (session == null) {
|
||||
resetSharedDevice(lib);
|
||||
deviceHandle = ensureSharedDeviceOpened(apiName, lib);
|
||||
session = openSessionOrThrow(apiName, lib, deviceHandle);
|
||||
}
|
||||
|
||||
Pointer session = sessionRef.getValue();
|
||||
try {
|
||||
return callback.apply(lib, deviceHandle, session);
|
||||
} finally {
|
||||
@@ -76,7 +68,7 @@ public class PcieSessionTemplate {
|
||||
log.warn("{} close session failed: {}", apiName, errorMapper.toMessage(closeSessionRc));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void ensureSuccess(String apiName, int retCode) {
|
||||
@@ -85,6 +77,13 @@ public class PcieSessionTemplate {
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
void closeSharedDevice() {
|
||||
synchronized (lock) {
|
||||
closeSharedDevice(libOrNull());
|
||||
}
|
||||
}
|
||||
|
||||
private PcieNativeLibrary ensureLibraryLoaded() {
|
||||
PcieNativeLibrary cached = nativeLibrary;
|
||||
if (cached != null) {
|
||||
@@ -116,4 +115,55 @@ public class PcieSessionTemplate {
|
||||
return nativeLibrary;
|
||||
}
|
||||
}
|
||||
|
||||
private Pointer ensureSharedDeviceOpened(String apiName, PcieNativeLibrary lib) {
|
||||
Pointer cached = sharedDeviceHandle;
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
PointerByReference deviceRef = new PointerByReference();
|
||||
int openRc = lib.SDF_OpenDevice(deviceRef);
|
||||
ensureSuccess(apiName + ":SDF_OpenDevice", openRc);
|
||||
sharedDeviceHandle = deviceRef.getValue();
|
||||
return sharedDeviceHandle;
|
||||
}
|
||||
|
||||
private Pointer tryOpenSession(String apiName, PcieNativeLibrary lib, Pointer deviceHandle) {
|
||||
PointerByReference sessionRef = new PointerByReference();
|
||||
int openSessionRc = lib.SDF_OpenSession(deviceHandle, sessionRef);
|
||||
if (openSessionRc == 0) {
|
||||
return sessionRef.getValue();
|
||||
}
|
||||
log.warn("{} open session failed, will reset shared device and retry once: {}", apiName, errorMapper.toMessage(openSessionRc));
|
||||
return null;
|
||||
}
|
||||
|
||||
private Pointer openSessionOrThrow(String apiName, PcieNativeLibrary lib, Pointer deviceHandle) {
|
||||
PointerByReference sessionRef = new PointerByReference();
|
||||
int openSessionRc = lib.SDF_OpenSession(deviceHandle, sessionRef);
|
||||
ensureSuccess(apiName + ":SDF_OpenSession", openSessionRc);
|
||||
return sessionRef.getValue();
|
||||
}
|
||||
|
||||
private void resetSharedDevice(PcieNativeLibrary lib) {
|
||||
closeSharedDevice(lib);
|
||||
}
|
||||
|
||||
private void closeSharedDevice(PcieNativeLibrary lib) {
|
||||
Pointer device = sharedDeviceHandle;
|
||||
if (device == null || lib == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
sharedDeviceHandle = null;
|
||||
int closeRc = lib.SDF_CloseDevice(device);
|
||||
if (closeRc != 0) {
|
||||
log.warn("close shared device failed: {}", errorMapper.toMessage(closeRc));
|
||||
}
|
||||
}
|
||||
|
||||
private PcieNativeLibrary libOrNull() {
|
||||
return nativeLibrary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ public interface PcieNativeLibrary extends Library {
|
||||
|
||||
int SDFE_InitIdentify(Pointer hSessionHandle, byte[] oldPin, int oldPinLen, byte[] newPin, int newPinLen);
|
||||
|
||||
int SDFE_DeviceStatusGet(Pointer hSessionHandle, Pointer pDeviceStatus);
|
||||
int SDFE_DeviceStatusGet(Pointer hSessionHandle, SdfeDeviceStatus deviceStatus);
|
||||
|
||||
int SDFE_DeviceSelfTest(Pointer hSessionHandle);
|
||||
|
||||
@@ -245,15 +245,15 @@ public interface PcieNativeLibrary extends Library {
|
||||
|
||||
int SDFE_UnlockUkey(Pointer hSessionHandle, byte[] adminPin, int adminPinLen, byte[] userPin, int userPinLen);
|
||||
|
||||
int SDFE_ReadLMKComponent(Pointer hSessionHandle, byte[] ukeyPin, int ukeyPinLen);
|
||||
int SDFE_ReadUkeyLMKComponent(Pointer hSessionHandle, byte[] ukeyPin, int ukeyPinLen);
|
||||
|
||||
int SDFE_ReadUkeyIKComponent(Pointer hSessionHandle, int keyType, byte[] ukeyPin, int ukeyPinLen);
|
||||
|
||||
int SDFE_GenerateCertificate(Pointer hSessionHandle, byte[] ukeyPin, int ukeyPinLen);
|
||||
int SDFE_GenerateUkeyCertificate(Pointer hSessionHandle, byte[] ukeyPin, int ukeyPinLen);
|
||||
|
||||
int SDFE_LoginoutAdmin(Pointer hSessionHandle, byte adminIndex);
|
||||
int SDFE_LoginoutUkey(Pointer hSessionHandle, byte adminIndex);
|
||||
|
||||
int SDFE_LoginStatus(Pointer hSessionHandle, SdfeLoginState loginState);
|
||||
int SDFE_UkeyLoginStatus(Pointer hSessionHandle, SdfeLoginState loginState);
|
||||
|
||||
int SDFE_HmacInit(Pointer hSessionHandle, int algId, byte[] key, int keyLen);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.cisd.tms.integration.crypto.pcie.jna;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
@Structure.FieldOrder({
|
||||
"type",
|
||||
"level",
|
||||
"devCount",
|
||||
"rsaKeyCount",
|
||||
@@ -13,6 +14,7 @@ import com.sun.jna.Structure;
|
||||
})
|
||||
public class SdfeDeviceConf extends Structure {
|
||||
|
||||
public int type;
|
||||
public int level;
|
||||
public int devCount;
|
||||
public int rsaKeyCount;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.cisd.tms.integration.crypto.pcie.jna;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
@Structure.FieldOrder({
|
||||
"fsmState",
|
||||
"dkeyState",
|
||||
"errorCode",
|
||||
"version",
|
||||
"commit",
|
||||
"frequency",
|
||||
"pcieSpeed",
|
||||
"pcieWidth",
|
||||
"chipTemp",
|
||||
"chipVoltage",
|
||||
"boardTemp",
|
||||
"boardVoltage",
|
||||
"boardCurrent",
|
||||
"chipTempmin",
|
||||
"chipTempmax",
|
||||
"boardVolmin",
|
||||
"boardVolmax",
|
||||
"fsTotalKb",
|
||||
"fsFreeKb"
|
||||
})
|
||||
public class SdfeDeviceStatus extends Structure {
|
||||
|
||||
public int fsmState;
|
||||
public int dkeyState;
|
||||
public int errorCode;
|
||||
public int version;
|
||||
public int commit;
|
||||
public int frequency;
|
||||
public int pcieSpeed;
|
||||
public int pcieWidth;
|
||||
public float chipTemp;
|
||||
public float chipVoltage;
|
||||
public float boardTemp;
|
||||
public float boardVoltage;
|
||||
public float boardCurrent;
|
||||
public float chipTempmin;
|
||||
public float chipTempmax;
|
||||
public float boardVolmin;
|
||||
public float boardVolmax;
|
||||
public int fsTotalKb;
|
||||
public int fsFreeKb;
|
||||
|
||||
public SdfeDeviceStatus() {
|
||||
super(ALIGN_NONE);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.cisd.tms.integration.crypto.pcie.model;
|
||||
|
||||
public class DeviceConfResult {
|
||||
|
||||
private int type;
|
||||
private int level;
|
||||
private int devCount;
|
||||
private int rsaKeyCount;
|
||||
@@ -10,6 +11,14 @@ public class DeviceConfResult {
|
||||
private int sessKeyCount;
|
||||
private int fileSysCapacity;
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,13 @@ public class DeviceInfoResult {
|
||||
private int symAlgAbility;
|
||||
private int hashAlgAbility;
|
||||
private int bufferSize;
|
||||
private String deviceVersionText;
|
||||
private String standardVersionText;
|
||||
private String asymmetricAlgorithmsText;
|
||||
private String asymmetricKeyBitsText;
|
||||
private String symmetricAlgorithmsText;
|
||||
private String hashAlgorithmsText;
|
||||
private String bufferSizeText;
|
||||
|
||||
public String getIssuerName() {
|
||||
return issuerName;
|
||||
@@ -92,4 +99,60 @@ public class DeviceInfoResult {
|
||||
public void setBufferSize(int bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public String getDeviceVersionText() {
|
||||
return deviceVersionText;
|
||||
}
|
||||
|
||||
public void setDeviceVersionText(String deviceVersionText) {
|
||||
this.deviceVersionText = deviceVersionText;
|
||||
}
|
||||
|
||||
public String getStandardVersionText() {
|
||||
return standardVersionText;
|
||||
}
|
||||
|
||||
public void setStandardVersionText(String standardVersionText) {
|
||||
this.standardVersionText = standardVersionText;
|
||||
}
|
||||
|
||||
public String getAsymmetricAlgorithmsText() {
|
||||
return asymmetricAlgorithmsText;
|
||||
}
|
||||
|
||||
public void setAsymmetricAlgorithmsText(String asymmetricAlgorithmsText) {
|
||||
this.asymmetricAlgorithmsText = asymmetricAlgorithmsText;
|
||||
}
|
||||
|
||||
public String getAsymmetricKeyBitsText() {
|
||||
return asymmetricKeyBitsText;
|
||||
}
|
||||
|
||||
public void setAsymmetricKeyBitsText(String asymmetricKeyBitsText) {
|
||||
this.asymmetricKeyBitsText = asymmetricKeyBitsText;
|
||||
}
|
||||
|
||||
public String getSymmetricAlgorithmsText() {
|
||||
return symmetricAlgorithmsText;
|
||||
}
|
||||
|
||||
public void setSymmetricAlgorithmsText(String symmetricAlgorithmsText) {
|
||||
this.symmetricAlgorithmsText = symmetricAlgorithmsText;
|
||||
}
|
||||
|
||||
public String getHashAlgorithmsText() {
|
||||
return hashAlgorithmsText;
|
||||
}
|
||||
|
||||
public void setHashAlgorithmsText(String hashAlgorithmsText) {
|
||||
this.hashAlgorithmsText = hashAlgorithmsText;
|
||||
}
|
||||
|
||||
public String getBufferSizeText() {
|
||||
return bufferSizeText;
|
||||
}
|
||||
|
||||
public void setBufferSizeText(String bufferSizeText) {
|
||||
this.bufferSizeText = bufferSizeText;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
package com.cisd.tms.integration.crypto.pcie.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
public class DeviceStatusResult {
|
||||
|
||||
@JsonIgnore
|
||||
private byte[] statusData;
|
||||
private int length;
|
||||
private String statusHex;
|
||||
private int fsmState;
|
||||
private String fsmStateText;
|
||||
private int commit;
|
||||
private String commitHex;
|
||||
private int frequencyMhz;
|
||||
private String frequencyText;
|
||||
private int pcieSpeed;
|
||||
private int pcieWidth;
|
||||
private String pcieInfoText;
|
||||
private double boardTempC;
|
||||
private String boardTempText;
|
||||
private double boardVoltageV;
|
||||
private String boardVoltageText;
|
||||
private int fsTotalKb;
|
||||
private String fsTotalText;
|
||||
private int fsFreeKb;
|
||||
private String fsFreeText;
|
||||
|
||||
public byte[] getStatusData() {
|
||||
return statusData;
|
||||
@@ -20,4 +41,148 @@ public class DeviceStatusResult {
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public String getStatusHex() {
|
||||
return statusHex;
|
||||
}
|
||||
|
||||
public void setStatusHex(String statusHex) {
|
||||
this.statusHex = statusHex;
|
||||
}
|
||||
|
||||
public int getFsmState() {
|
||||
return fsmState;
|
||||
}
|
||||
|
||||
public void setFsmState(int fsmState) {
|
||||
this.fsmState = fsmState;
|
||||
}
|
||||
|
||||
public String getFsmStateText() {
|
||||
return fsmStateText;
|
||||
}
|
||||
|
||||
public void setFsmStateText(String fsmStateText) {
|
||||
this.fsmStateText = fsmStateText;
|
||||
}
|
||||
|
||||
public int getCommit() {
|
||||
return commit;
|
||||
}
|
||||
|
||||
public void setCommit(int commit) {
|
||||
this.commit = commit;
|
||||
}
|
||||
|
||||
public String getCommitHex() {
|
||||
return commitHex;
|
||||
}
|
||||
|
||||
public void setCommitHex(String commitHex) {
|
||||
this.commitHex = commitHex;
|
||||
}
|
||||
|
||||
public int getFrequencyMhz() {
|
||||
return frequencyMhz;
|
||||
}
|
||||
|
||||
public void setFrequencyMhz(int frequencyMhz) {
|
||||
this.frequencyMhz = frequencyMhz;
|
||||
}
|
||||
|
||||
public String getFrequencyText() {
|
||||
return frequencyText;
|
||||
}
|
||||
|
||||
public void setFrequencyText(String frequencyText) {
|
||||
this.frequencyText = frequencyText;
|
||||
}
|
||||
|
||||
public int getPcieSpeed() {
|
||||
return pcieSpeed;
|
||||
}
|
||||
|
||||
public void setPcieSpeed(int pcieSpeed) {
|
||||
this.pcieSpeed = pcieSpeed;
|
||||
}
|
||||
|
||||
public int getPcieWidth() {
|
||||
return pcieWidth;
|
||||
}
|
||||
|
||||
public void setPcieWidth(int pcieWidth) {
|
||||
this.pcieWidth = pcieWidth;
|
||||
}
|
||||
|
||||
public String getPcieInfoText() {
|
||||
return pcieInfoText;
|
||||
}
|
||||
|
||||
public void setPcieInfoText(String pcieInfoText) {
|
||||
this.pcieInfoText = pcieInfoText;
|
||||
}
|
||||
|
||||
public double getBoardTempC() {
|
||||
return boardTempC;
|
||||
}
|
||||
|
||||
public void setBoardTempC(double boardTempC) {
|
||||
this.boardTempC = boardTempC;
|
||||
}
|
||||
|
||||
public String getBoardTempText() {
|
||||
return boardTempText;
|
||||
}
|
||||
|
||||
public void setBoardTempText(String boardTempText) {
|
||||
this.boardTempText = boardTempText;
|
||||
}
|
||||
|
||||
public double getBoardVoltageV() {
|
||||
return boardVoltageV;
|
||||
}
|
||||
|
||||
public void setBoardVoltageV(double boardVoltageV) {
|
||||
this.boardVoltageV = boardVoltageV;
|
||||
}
|
||||
|
||||
public String getBoardVoltageText() {
|
||||
return boardVoltageText;
|
||||
}
|
||||
|
||||
public void setBoardVoltageText(String boardVoltageText) {
|
||||
this.boardVoltageText = boardVoltageText;
|
||||
}
|
||||
|
||||
public int getFsTotalKb() {
|
||||
return fsTotalKb;
|
||||
}
|
||||
|
||||
public void setFsTotalKb(int fsTotalKb) {
|
||||
this.fsTotalKb = fsTotalKb;
|
||||
}
|
||||
|
||||
public String getFsTotalText() {
|
||||
return fsTotalText;
|
||||
}
|
||||
|
||||
public void setFsTotalText(String fsTotalText) {
|
||||
this.fsTotalText = fsTotalText;
|
||||
}
|
||||
|
||||
public int getFsFreeKb() {
|
||||
return fsFreeKb;
|
||||
}
|
||||
|
||||
public void setFsFreeKb(int fsFreeKb) {
|
||||
this.fsFreeKb = fsFreeKb;
|
||||
}
|
||||
|
||||
public String getFsFreeText() {
|
||||
return fsFreeText;
|
||||
}
|
||||
|
||||
public void setFsFreeText(String fsFreeText) {
|
||||
this.fsFreeText = fsFreeText;
|
||||
}
|
||||
}
|
||||
|
||||
+59
-21
@@ -16,6 +16,7 @@ import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPrivateKey;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPublicKey;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfDeviceInfo;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceConf;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceStatus;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfeKekComponent;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfeLmkComponent;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfeLoginState;
|
||||
@@ -129,6 +130,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
conf.read();
|
||||
|
||||
DeviceConfResult result = new DeviceConfResult();
|
||||
result.setType(conf.type);
|
||||
result.setLevel(conf.level);
|
||||
result.setDevCount(conf.devCount);
|
||||
result.setRsaKeyCount(conf.rsaKeyCount);
|
||||
@@ -158,6 +160,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
result.setSymAlgAbility(info.symAlgAbility);
|
||||
result.setHashAlgAbility(info.hashAlgAbility);
|
||||
result.setBufferSize(info.bufferSize);
|
||||
PcieDeviceInfoFormatter.enrich(result);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
@@ -192,6 +195,40 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] initializeMasterKey(byte[] oldPin, byte[] newPin) {
|
||||
byte[] oldPinValue = requireNonEmptyBytes("oldPin", oldPin);
|
||||
byte[] newPinValue = requireNonEmptyBytes("newPin", newPin);
|
||||
|
||||
try {
|
||||
return sessionTemplate.withSession("SDFE_InitializeMasterKey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_InitIdentify",
|
||||
lib.SDFE_InitIdentify(sessionHandle, oldPinValue, oldPinValue.length, newPinValue, newPinValue.length)
|
||||
);
|
||||
sessionTemplate.ensureSuccess("SDFE_GenerateLMK", lib.SDFE_GenerateLMK(sessionHandle));
|
||||
sessionTemplate.ensureSuccess("SDFE_LoadLMK", lib.SDFE_LoadLMK(sessionHandle));
|
||||
sessionTemplate.ensureSuccess("SDFE_GenerateIK", lib.SDFE_GenerateIK(sessionHandle, IK_KEY_TYPE_DEVICE));
|
||||
sessionTemplate.ensureSuccess("SDFE_GenerateIK", lib.SDFE_GenerateIK(sessionHandle, IK_KEY_TYPE_AUTH));
|
||||
|
||||
int retCode = lib.SDFE_CheckLMK(sessionHandle);
|
||||
if (retCode != 0) {
|
||||
if ((retCode & 0xFF) == SDFE_INIT_STATUS_LOW_BYTE) {
|
||||
throw new IllegalStateException("master key initialization failed");
|
||||
}
|
||||
sessionTemplate.ensureSuccess("SDFE_CheckLMK", retCode);
|
||||
}
|
||||
|
||||
byte[] mac = new byte[LMK_SEED_MAC_LENGTH];
|
||||
sessionTemplate.ensureSuccess("SDFE_ExportLMKSeedMAC", lib.SDFE_ExportLMKSeedMAC(sessionHandle, mac));
|
||||
return Arrays.copyOf(mac, mac.length);
|
||||
});
|
||||
} finally {
|
||||
wipe(oldPinValue);
|
||||
wipe(newPinValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceSelfTest() {
|
||||
sessionTemplate.withSession("SDFE_DeviceSelfTest", (lib, deviceHandle, sessionHandle) -> {
|
||||
@@ -202,15 +239,16 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
|
||||
@Override
|
||||
public DeviceStatusResult getDeviceStatus() {
|
||||
int size = 8;
|
||||
|
||||
return sessionTemplate.withSession("SDFE_DeviceStatusGet", (lib, deviceHandle, sessionHandle) -> {
|
||||
Memory statusMemory = new Memory(8);
|
||||
sessionTemplate.ensureSuccess("SDFE_DeviceStatusGet", lib.SDFE_DeviceStatusGet(sessionHandle, statusMemory));
|
||||
SdfeDeviceStatus status = new SdfeDeviceStatus();
|
||||
sessionTemplate.ensureSuccess("SDFE_DeviceStatusGet", lib.SDFE_DeviceStatusGet(sessionHandle, status));
|
||||
status.read();
|
||||
int size = status.size();
|
||||
|
||||
DeviceStatusResult result = new DeviceStatusResult();
|
||||
// result.setLength(size);
|
||||
result.setStatusData(statusMemory.getByteArray(0, size));
|
||||
result.setLength(size);
|
||||
result.setStatusData(status.getPointer().getByteArray(0, size));
|
||||
PcieDeviceStatusFormatter.enrich(result, status);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
@@ -1611,15 +1649,9 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupDataResult backupLmkEx(int outBufferSize) {
|
||||
int size = requirePositive("outBufferSize", outBufferSize);
|
||||
|
||||
public BackupDataResult backupLmkEx() {
|
||||
return sessionTemplate.withSession("SDFE_BackupLMK_EX", (lib, deviceHandle, sessionHandle) -> {
|
||||
SdfeLmkComponent output = new SdfeLmkComponent();
|
||||
int structSize = output.size();
|
||||
if (size < structSize) {
|
||||
throw new IllegalArgumentException("outBufferSize must be >= " + structSize);
|
||||
}
|
||||
sessionTemplate.ensureSuccess("SDFE_BackupLMK_EX", lib.SDFE_BackupLMK_EX(sessionHandle, output));
|
||||
byte[] outputBytes = toBytes(output);
|
||||
return toBackupResult("SDFE_BackupLMK_EX", outputBytes, outputBytes.length);
|
||||
@@ -1781,8 +1813,11 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
|
||||
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_ReadLMKComponent", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_ReadLMKComponent", lib.SDFE_ReadLMKComponent(sessionHandle, pin, pin.length));
|
||||
sessionTemplate.withSession("SDFE_ReadUkeyLMKComponent", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ReadUkeyLMKComponent",
|
||||
lib.SDFE_ReadUkeyLMKComponent(sessionHandle, pin, pin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
@@ -1813,8 +1848,11 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
|
||||
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_GenerateCertificate", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_GenerateCertificate", lib.SDFE_GenerateCertificate(sessionHandle, pin, pin.length));
|
||||
sessionTemplate.withSession("SDFE_GenerateUkeyCertificate", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_GenerateUkeyCertificate",
|
||||
lib.SDFE_GenerateUkeyCertificate(sessionHandle, pin, pin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
@@ -1826,17 +1864,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
public void logoutAdmin(int adminIndex) {
|
||||
int safeAdminIndex = requireByteRange("adminIndex", adminIndex);
|
||||
|
||||
sessionTemplate.withSession("SDFE_LoginoutAdmin", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_LoginoutAdmin", lib.SDFE_LoginoutAdmin(sessionHandle, (byte) safeAdminIndex));
|
||||
sessionTemplate.withSession("SDFE_LoginoutUkey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_LoginoutUkey", lib.SDFE_LoginoutUkey(sessionHandle, (byte) safeAdminIndex));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginStatusResult loginStatus() {
|
||||
return sessionTemplate.withSession("SDFE_LoginStatus", (lib, deviceHandle, sessionHandle) -> {
|
||||
return sessionTemplate.withSession("SDFE_UkeyLoginStatus", (lib, deviceHandle, sessionHandle) -> {
|
||||
SdfeLoginState state = new SdfeLoginState();
|
||||
sessionTemplate.ensureSuccess("SDFE_LoginStatus", lib.SDFE_LoginStatus(sessionHandle, state));
|
||||
sessionTemplate.ensureSuccess("SDFE_UkeyLoginStatus", lib.SDFE_UkeyLoginStatus(sessionHandle, state));
|
||||
state.read();
|
||||
|
||||
LoginStatusResult result = new LoginStatusResult();
|
||||
|
||||
+17
-4
@@ -2,6 +2,7 @@ package com.cisd.tms.integration.crypto.pcie.service;
|
||||
|
||||
import com.cisd.tms.integration.crypto.pcie.PcieKeyState;
|
||||
import com.cisd.tms.integration.crypto.pcie.PcieUserKeyType;
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceStatus;
|
||||
import com.cisd.tms.integration.crypto.pcie.model.AgreementDataAndKeyEccResult;
|
||||
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
|
||||
import com.cisd.tms.integration.crypto.pcie.model.ChangePrivateKeyPasswordRequest;
|
||||
@@ -100,6 +101,19 @@ public class MockPcieCryptoService implements PcieCryptoService {
|
||||
requireNonEmptyBytes("newPin", newPin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] initializeMasterKey(byte[] oldPin, byte[] newPin) {
|
||||
initIdentify(oldPin, newPin);
|
||||
generateLmk();
|
||||
loadLmk();
|
||||
generateIk(1);
|
||||
generateIk(2);
|
||||
if (!checkLmk()) {
|
||||
throw new IllegalStateException("master key initialization failed");
|
||||
}
|
||||
return exportLmkSeedMac();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceSelfTest() {
|
||||
// no-op
|
||||
@@ -107,7 +121,7 @@ public class MockPcieCryptoService implements PcieCryptoService {
|
||||
|
||||
@Override
|
||||
public DeviceStatusResult getDeviceStatus() {
|
||||
int size = 8;
|
||||
int size = new SdfeDeviceStatus().size();
|
||||
DeviceStatusResult result = new DeviceStatusResult();
|
||||
result.setLength(size);
|
||||
result.setStatusData(new byte[size]);
|
||||
@@ -679,9 +693,8 @@ public class MockPcieCryptoService implements PcieCryptoService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupDataResult backupLmkEx(int outBufferSize) {
|
||||
int size = requirePositive("outBufferSize", outBufferSize);
|
||||
return mockBackup(size, 0x11);
|
||||
public BackupDataResult backupLmkEx() {
|
||||
return mockBackup(new com.cisd.tms.integration.crypto.pcie.jna.SdfeLmkComponent().size(), 0x11);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,6 +71,8 @@ public interface PcieCryptoService {
|
||||
|
||||
void initIdentify(byte[] oldPin, byte[] newPin);
|
||||
|
||||
byte[] initializeMasterKey(byte[] oldPin, byte[] newPin);
|
||||
|
||||
void deviceSelfTest();
|
||||
|
||||
DeviceStatusResult getDeviceStatus();
|
||||
@@ -209,7 +211,7 @@ public interface PcieCryptoService {
|
||||
|
||||
byte[] exportLmkSeedMac();
|
||||
|
||||
BackupDataResult backupLmkEx(int outBufferSize);
|
||||
BackupDataResult backupLmkEx();
|
||||
|
||||
void recoverLmkEx(byte[] lmkComponent);
|
||||
|
||||
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
package com.cisd.tms.integration.crypto.pcie.service;
|
||||
|
||||
import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
final class PcieDeviceInfoFormatter {
|
||||
|
||||
private static final int ASYM_RSA = 0x00010000;
|
||||
private static final int ASYM_SM2_SIGN = 0x00020200;
|
||||
private static final int ASYM_SM2_DH = 0x00020400;
|
||||
private static final int ASYM_SM2_ENC = 0x00020800;
|
||||
|
||||
private static final int SYM_SM1 = 0x00000100;
|
||||
private static final int SYM_SM4 = 0x00000400;
|
||||
private static final int SYM_AES128 = 0x00008000;
|
||||
private static final int SYM_AES192 = 0x00010000;
|
||||
private static final int SYM_AES256 = 0x00020000;
|
||||
|
||||
private static final int HASH_SM3 = 0x00000001;
|
||||
private static final int HASH_SHA256 = 0x00000004;
|
||||
|
||||
private static final int ASYM_BITS_256 = 0x00000100;
|
||||
private static final int ASYM_BITS_2048 = 0x08000000;
|
||||
|
||||
private PcieDeviceInfoFormatter() {
|
||||
}
|
||||
|
||||
static void enrich(DeviceInfoResult result) {
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
result.setDeviceVersionText(formatDeviceVersion(result.getDeviceVersion()));
|
||||
result.setStandardVersionText(formatStandardVersion(result.getStandardVersion()));
|
||||
result.setAsymmetricAlgorithmsText(joinNonEmpty(decodeAsymmetricAlgorithms(result.getAsymAlgAbility0())));
|
||||
result.setAsymmetricKeyBitsText(joinNonEmpty(decodeAsymmetricKeyBits(result.getAsymAlgAbility1())));
|
||||
result.setSymmetricAlgorithmsText(joinNonEmpty(decodeSymmetricAlgorithms(result.getSymAlgAbility())));
|
||||
result.setHashAlgorithmsText(joinNonEmpty(decodeHashAlgorithms(result.getHashAlgAbility())));
|
||||
result.setBufferSizeText(formatBufferSize(result.getBufferSize()));
|
||||
}
|
||||
|
||||
private static String formatDeviceVersion(int rawValue) {
|
||||
byte[] bytes = ByteBuffer.allocate(Integer.BYTES)
|
||||
.order(ByteOrder.LITTLE_ENDIAN)
|
||||
.putInt(rawValue)
|
||||
.array();
|
||||
String decoded = new String(bytes, StandardCharsets.US_ASCII)
|
||||
.replace("\u0000", "")
|
||||
.trim();
|
||||
if (!decoded.isEmpty() && decoded.chars().allMatch(PcieDeviceInfoFormatter::isPrintableVersionChar)) {
|
||||
return decoded.startsWith("V") ? decoded : "V" + decoded;
|
||||
}
|
||||
return "0x" + Integer.toHexString(rawValue);
|
||||
}
|
||||
|
||||
private static boolean isPrintableVersionChar(int value) {
|
||||
return (value >= '0' && value <= '9') || value == '.' || value == 'V' || value == 'v';
|
||||
}
|
||||
|
||||
private static String formatStandardVersion(int rawValue) {
|
||||
int standard = (rawValue >>> 16) & 0xFFFF;
|
||||
int yearHi = (rawValue >>> 8) & 0xFF;
|
||||
int yearLo = rawValue & 0xFF;
|
||||
if (standard > 0 && yearHi > 0 && yearLo > 0) {
|
||||
return String.format("GMT %04x-%02x%02x", standard, yearHi, yearLo).toUpperCase();
|
||||
}
|
||||
return "0x" + Integer.toHexString(rawValue);
|
||||
}
|
||||
|
||||
private static List<String> decodeAsymmetricAlgorithms(int rawValue) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if ((rawValue & ASYM_SM2_SIGN) == ASYM_SM2_SIGN) {
|
||||
values.add("SM2_SIGN");
|
||||
}
|
||||
if ((rawValue & ASYM_SM2_DH) == ASYM_SM2_DH) {
|
||||
values.add("SM2_DH");
|
||||
}
|
||||
if ((rawValue & ASYM_SM2_ENC) == ASYM_SM2_ENC) {
|
||||
values.add("SM2_ENC");
|
||||
}
|
||||
if ((rawValue & ASYM_RSA) == ASYM_RSA) {
|
||||
values.add("RSA");
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private static List<String> decodeAsymmetricKeyBits(int rawValue) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if ((rawValue & ASYM_BITS_256) == ASYM_BITS_256) {
|
||||
values.add("256");
|
||||
}
|
||||
if ((rawValue & ASYM_BITS_2048) == ASYM_BITS_2048) {
|
||||
values.add("2048");
|
||||
}
|
||||
if (!values.isEmpty()) {
|
||||
values.add("bits");
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private static List<String> decodeSymmetricAlgorithms(int rawValue) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if ((rawValue & SYM_SM1) == SYM_SM1) {
|
||||
values.add("SM1");
|
||||
}
|
||||
if ((rawValue & SYM_SM4) == SYM_SM4) {
|
||||
values.add("SM4");
|
||||
}
|
||||
if ((rawValue & SYM_AES128) == SYM_AES128) {
|
||||
values.add("AES128");
|
||||
}
|
||||
if ((rawValue & SYM_AES192) == SYM_AES192) {
|
||||
values.add("AES192");
|
||||
}
|
||||
if ((rawValue & SYM_AES256) == SYM_AES256) {
|
||||
values.add("AES256");
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private static List<String> decodeHashAlgorithms(int rawValue) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if ((rawValue & HASH_SM3) == HASH_SM3) {
|
||||
values.add("SM3");
|
||||
}
|
||||
if ((rawValue & HASH_SHA256) == HASH_SHA256) {
|
||||
values.add("SHA256");
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private static String formatBufferSize(int rawValue) {
|
||||
if (rawValue > 0 && rawValue % 1024 == 0) {
|
||||
return (rawValue / 1024) + " KB";
|
||||
}
|
||||
return rawValue + " B";
|
||||
}
|
||||
|
||||
private static String joinNonEmpty(List<String> values) {
|
||||
return String.join(" ", values);
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package com.cisd.tms.integration.crypto.pcie.service;
|
||||
|
||||
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceStatus;
|
||||
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
|
||||
import java.util.Arrays;
|
||||
import java.util.HexFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class PcieDeviceStatusFormatter {
|
||||
|
||||
private PcieDeviceStatusFormatter() {
|
||||
}
|
||||
|
||||
static void enrich(DeviceStatusResult result, SdfeDeviceStatus status) {
|
||||
if (result == null || status == null) {
|
||||
return;
|
||||
}
|
||||
byte[] normalized = normalize(result.getStatusData(), result.getLength());
|
||||
result.setLength(normalized.length);
|
||||
result.setStatusHex(HexFormat.of().formatHex(normalized));
|
||||
result.setFsmState(status.fsmState);
|
||||
result.setFsmStateText(formatFsmState(status.fsmState));
|
||||
result.setCommit(status.commit);
|
||||
result.setCommitHex(String.format(Locale.ROOT, "0x%08x", status.commit));
|
||||
result.setFrequencyMhz(status.frequency);
|
||||
result.setFrequencyText(status.frequency + "M");
|
||||
result.setPcieSpeed(status.pcieSpeed);
|
||||
result.setPcieWidth(status.pcieWidth);
|
||||
result.setPcieInfoText(formatPcieInfo(status.pcieSpeed, status.pcieWidth));
|
||||
result.setBoardTempC(round(status.boardTemp));
|
||||
result.setBoardTempText(formatFloat(status.boardTemp, "°C"));
|
||||
result.setBoardVoltageV(round(status.boardVoltage));
|
||||
result.setBoardVoltageText(formatFloat(status.boardVoltage, "V"));
|
||||
result.setFsTotalKb(status.fsTotalKb);
|
||||
result.setFsTotalText(status.fsTotalKb + " KB");
|
||||
result.setFsFreeKb(status.fsFreeKb);
|
||||
result.setFsFreeText(status.fsFreeKb + " KB");
|
||||
}
|
||||
|
||||
public static void ensureHex(DeviceStatusResult result) {
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
if (result.getStatusHex() == null || result.getStatusHex().isBlank()) {
|
||||
byte[] normalized = normalize(result.getStatusData(), result.getLength());
|
||||
result.setLength(normalized.length);
|
||||
result.setStatusHex(HexFormat.of().formatHex(normalized));
|
||||
}
|
||||
}
|
||||
|
||||
private static String formatFsmState(int fsmState) {
|
||||
return switch (fsmState) {
|
||||
case 0 -> "就绪状态";
|
||||
case 1 -> "未初始化状态";
|
||||
default -> "状态码:" + fsmState;
|
||||
};
|
||||
}
|
||||
|
||||
private static String formatPcieInfo(int speed, int width) {
|
||||
if (speed <= 0 || width <= 0) {
|
||||
return "";
|
||||
}
|
||||
return "GEN" + speed + " X" + width;
|
||||
}
|
||||
|
||||
private static double round(float value) {
|
||||
return Math.round(value * 100.0d) / 100.0d;
|
||||
}
|
||||
|
||||
private static String formatFloat(float value, String unit) {
|
||||
return String.format(Locale.ROOT, "%.2f %s", round(value), unit);
|
||||
}
|
||||
|
||||
private static byte[] normalize(byte[] data, int length) {
|
||||
if (data == null || data.length == 0) {
|
||||
return new byte[0];
|
||||
}
|
||||
int safeLength = length > 0 && length <= data.length ? length : data.length;
|
||||
return Arrays.copyOf(data, safeLength);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,26 @@
|
||||
package com.cisd.tms.modules.auth.controller;
|
||||
|
||||
import com.cisd.tms.common.api.ApiResponse;
|
||||
import com.cisd.tms.modules.auth.dto.ChangePasswordRequest;
|
||||
import com.cisd.tms.modules.auth.dto.CurrentUserResponse;
|
||||
import com.cisd.tms.modules.auth.dto.LoginRequest;
|
||||
import com.cisd.tms.modules.auth.dto.LoginResponse;
|
||||
import com.cisd.tms.modules.auth.dto.UkeyBindRequest;
|
||||
import com.cisd.tms.modules.auth.security.RequireAuthLevel;
|
||||
import com.cisd.tms.modules.auth.security.RequireRole;
|
||||
import com.cisd.tms.modules.auth.service.AuthAdminService;
|
||||
import com.cisd.tms.modules.auth.service.AuthService;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignDTO;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignResult;
|
||||
import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@@ -22,23 +30,108 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class AuthController {
|
||||
|
||||
private final AuthService authService;
|
||||
private final AuthAdminService authAdminService;
|
||||
|
||||
public AuthController(AuthService authService) {
|
||||
public AuthController(AuthService authService, AuthAdminService authAdminService) {
|
||||
this.authService = authService;
|
||||
this.authAdminService = authAdminService;
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
@Operation(summary = "内部用户登录", description = "校验用户名和密码,返回访问令牌及过期时间。")
|
||||
@Operation(summary = "内部用户登录", description = "校验角色口令,可选校验 UKey 序列号,返回访问令牌和认证等级。")
|
||||
public ApiResponse<LoginResponse> login(@Valid @RequestBody LoginRequest request) {
|
||||
return ApiResponse.success(authService.login(request));
|
||||
}
|
||||
|
||||
@GetMapping("/me")
|
||||
@Operation(summary = "查询当前用户", description = "根据请求头中的用户标识返回当前登录用户信息。")
|
||||
public ApiResponse<CurrentUserResponse> me(
|
||||
@Parameter(description = "当前用户标识,来自内部鉴权链路透传的 X-User 请求头")
|
||||
@RequestHeader(value = "X-User", required = false) String user
|
||||
@Operation(summary = "查询当前用户", description = "根据内部鉴权链路透传的当前角色标识返回当前登录用户信息。")
|
||||
public ApiResponse<CurrentUserResponse> me(HttpServletRequest request) {
|
||||
String user = (String) request.getAttribute(com.cisd.tms.security.internal.InternalApiAuthInterceptor.ATTR_ROLE_CODE);
|
||||
String sessionToken = (String) request.getAttribute(com.cisd.tms.security.internal.InternalApiAuthInterceptor.ATTR_SESSION_TOKEN);
|
||||
return ApiResponse.success(authService.me(user, sessionToken));
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
@Operation(summary = "退出当前会话", description = "使当前内部管理端会话失效。")
|
||||
public ApiResponse<Void> logout(HttpServletRequest request) {
|
||||
authService.logout((String) request.getAttribute(InternalApiAuthInterceptor.ATTR_SESSION_TOKEN));
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/change-password")
|
||||
@Operation(summary = "修改当前角色口令", description = "基于当前登录会话校验并更新角色口令。")
|
||||
public ApiResponse<Void> changePassword(@Valid @RequestBody ChangePasswordRequest request, HttpServletRequest httpRequest) {
|
||||
authService.changePassword(
|
||||
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_SESSION_TOKEN),
|
||||
request.getCurrentPassword(),
|
||||
request.getNewPassword()
|
||||
);
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/roles/{roleCode}/enable")
|
||||
@Operation(summary = "启用角色", description = "仅允许密钥管理员 FULL 会话启用目标角色。")
|
||||
@RequireRole("KEY_ADMIN")
|
||||
@RequireAuthLevel("FULL")
|
||||
public ApiResponse<Void> enableRole(@PathVariable("roleCode") String roleCode, HttpServletRequest request) {
|
||||
authAdminService.enableRole(
|
||||
(String) request.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE),
|
||||
(String) request.getAttribute(InternalApiAuthInterceptor.ATTR_AUTH_LEVEL),
|
||||
roleCode
|
||||
);
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/roles/{roleCode}/reset-password")
|
||||
@Operation(summary = "重置角色密码", description = "仅允许密钥管理员 FULL 会话重置目标角色密码。")
|
||||
@RequireRole("KEY_ADMIN")
|
||||
@RequireAuthLevel("FULL")
|
||||
public ApiResponse<Void> resetPassword(@PathVariable("roleCode") String roleCode, HttpServletRequest request) {
|
||||
authAdminService.resetPassword(
|
||||
(String) request.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE),
|
||||
(String) request.getAttribute(InternalApiAuthInterceptor.ATTR_AUTH_LEVEL),
|
||||
roleCode
|
||||
);
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/roles/{roleCode}/ukeys/bind")
|
||||
@Operation(summary = "绑定角色 UKey", description = "仅允许密钥管理员 FULL 会话绑定或覆盖目标角色槽位上的 UKey。")
|
||||
@RequireRole("KEY_ADMIN")
|
||||
@RequireAuthLevel("FULL")
|
||||
public ApiResponse<Void> bindUkey(
|
||||
@PathVariable("roleCode") String roleCode,
|
||||
@Valid @RequestBody UkeyBindRequest request,
|
||||
HttpServletRequest httpRequest
|
||||
) {
|
||||
return ApiResponse.success(authService.me(user));
|
||||
authAdminService.bindIssuedUkey(
|
||||
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE),
|
||||
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_AUTH_LEVEL),
|
||||
roleCode,
|
||||
request.getSlotNo(),
|
||||
request.getUkeySerial(),
|
||||
request.getUkeyPubkey(),
|
||||
request.getUid(),
|
||||
request.getRid(),
|
||||
request.getIssuerSign()
|
||||
);
|
||||
return ApiResponse.success();
|
||||
}
|
||||
|
||||
@PostMapping("/roles/{roleCode}/ukeys/issue-sign")
|
||||
@Operation(summary = "生成绑定用 UKey 发行签名", description = "按旧管理端绑定流程为目标角色的 UKey 信息出具发行签名。")
|
||||
@RequireRole("KEY_ADMIN")
|
||||
@RequireAuthLevel("FULL")
|
||||
public ApiResponse<UKeySignResult> issueUkeyBindingSign(
|
||||
@PathVariable("roleCode") String roleCode,
|
||||
@RequestBody UKeySignDTO request,
|
||||
HttpServletRequest httpRequest
|
||||
) {
|
||||
return ApiResponse.success(authAdminService.issueUkeyBindingSign(
|
||||
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE),
|
||||
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_AUTH_LEVEL),
|
||||
roleCode,
|
||||
request
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.cisd.tms.modules.auth.controller;
|
||||
|
||||
import com.cisd.tms.common.api.ApiResponse;
|
||||
import com.cisd.tms.modules.auth.dto.CompatPasswordLoginRequest;
|
||||
import com.cisd.tms.modules.auth.dto.CompatUkeyLoginRequest;
|
||||
import com.cisd.tms.modules.auth.dto.LoginResponse;
|
||||
import com.cisd.tms.modules.auth.dto.UkeyLoginRandomResponse;
|
||||
import com.cisd.tms.modules.auth.service.CompatAuthService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/auth")
|
||||
@Tag(name = "认证兼容接口", description = "兼容旧管理端的口令登录、UKey 登录与随机数接口")
|
||||
public class CompatAuthController {
|
||||
|
||||
private final CompatAuthService compatAuthService;
|
||||
|
||||
public CompatAuthController(CompatAuthService compatAuthService) {
|
||||
this.compatAuthService = compatAuthService;
|
||||
}
|
||||
|
||||
@GetMapping("/ukey-login/randoms")
|
||||
@Operation(summary = "生成 UKey 登录随机数", description = "兼容旧登录流程,为指定角色生成一组待签名随机数。")
|
||||
public ApiResponse<UkeyLoginRandomResponse> issueUkeyLoginRandoms(
|
||||
@RequestParam("role") String role,
|
||||
@RequestParam(value = "count", required = false) Integer count
|
||||
) {
|
||||
return ApiResponse.success(compatAuthService.issueUkeyLoginRandoms(role, count));
|
||||
}
|
||||
|
||||
@PostMapping("/password-login")
|
||||
@Operation(summary = "兼容口令登录", description = "兼容旧管理端的角色口令登录语义,底层复用当前会话体系。")
|
||||
public ApiResponse<LoginResponse> passwordLogin(@Valid @RequestBody CompatPasswordLoginRequest request) {
|
||||
return ApiResponse.success(compatAuthService.passwordLogin(request));
|
||||
}
|
||||
|
||||
@PostMapping("/ukey-login")
|
||||
@Operation(summary = "兼容 UKey 登录", description = "兼容旧管理端的 UKey 登录语义,校验发行签名、随机数和登录签名。")
|
||||
public ApiResponse<LoginResponse> ukeyLogin(@Valid @RequestBody CompatUkeyLoginRequest request) {
|
||||
return ApiResponse.success(compatAuthService.ukeyLogin(request));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.cisd.tms.modules.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
@Schema(description = "修改当前角色口令请求")
|
||||
public class ChangePasswordRequest {
|
||||
|
||||
@NotBlank(message = "currentPassword is required")
|
||||
@Schema(description = "当前口令", example = "12345678")
|
||||
private String currentPassword;
|
||||
|
||||
@NotBlank(message = "newPassword is required")
|
||||
@Schema(description = "新口令", example = "87654321")
|
||||
private String newPassword;
|
||||
|
||||
public String getCurrentPassword() {
|
||||
return currentPassword;
|
||||
}
|
||||
|
||||
public void setCurrentPassword(String currentPassword) {
|
||||
this.currentPassword = currentPassword;
|
||||
}
|
||||
|
||||
public String getNewPassword() {
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public void setNewPassword(String newPassword) {
|
||||
this.newPassword = newPassword;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.cisd.tms.modules.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
@Schema(description = "兼容旧管理端的口令登录请求")
|
||||
public class CompatPasswordLoginRequest {
|
||||
|
||||
@NotBlank(message = "role is required")
|
||||
@Schema(description = "角色标识,兼容旧角色名称", example = "auditadmin")
|
||||
private String role;
|
||||
|
||||
@NotBlank(message = "password is required")
|
||||
@Schema(description = "登录口令", example = "12345678")
|
||||
private String password;
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.cisd.tms.modules.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "兼容旧管理端的 UKey 登录请求")
|
||||
public class CompatUkeyLoginRequest {
|
||||
|
||||
@NotBlank(message = "role is required")
|
||||
@Schema(description = "角色标识,兼容旧角色名称", example = "keyadmin")
|
||||
private String role;
|
||||
|
||||
@NotBlank(message = "password is required")
|
||||
@Schema(description = "登录口令", example = "12345678")
|
||||
private String password;
|
||||
|
||||
@Valid
|
||||
@NotEmpty(message = "authInfo is required")
|
||||
@Schema(description = "UKey 登录认证材料")
|
||||
private List<LoginAuthInfo> authInfo;
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public List<LoginAuthInfo> getAuthInfo() {
|
||||
return authInfo;
|
||||
}
|
||||
|
||||
public void setAuthInfo(List<LoginAuthInfo> authInfo) {
|
||||
this.authInfo = authInfo;
|
||||
}
|
||||
|
||||
@Schema(description = "单个 UKey 登录认证项")
|
||||
public static class LoginAuthInfo {
|
||||
@NotBlank(message = "pubKey is required")
|
||||
private String pubKey;
|
||||
@NotBlank(message = "uid is required")
|
||||
private String uid;
|
||||
@NotBlank(message = "rid is required")
|
||||
private String rid;
|
||||
@NotBlank(message = "ra is required")
|
||||
private String ra;
|
||||
@NotBlank(message = "rb is required")
|
||||
private String rb;
|
||||
@NotBlank(message = "issueSign is required")
|
||||
private String issueSign;
|
||||
@NotBlank(message = "loginSignData is required")
|
||||
private String loginSignData;
|
||||
@NotBlank(message = "loginSign is required")
|
||||
private String loginSign;
|
||||
|
||||
public String getPubKey() {
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
public void setPubKey(String pubKey) {
|
||||
this.pubKey = pubKey;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public String getRid() {
|
||||
return rid;
|
||||
}
|
||||
|
||||
public void setRid(String rid) {
|
||||
this.rid = rid;
|
||||
}
|
||||
|
||||
public String getRa() {
|
||||
return ra;
|
||||
}
|
||||
|
||||
public void setRa(String ra) {
|
||||
this.ra = ra;
|
||||
}
|
||||
|
||||
public String getRb() {
|
||||
return rb;
|
||||
}
|
||||
|
||||
public void setRb(String rb) {
|
||||
this.rb = rb;
|
||||
}
|
||||
|
||||
public String getIssueSign() {
|
||||
return issueSign;
|
||||
}
|
||||
|
||||
public void setIssueSign(String issueSign) {
|
||||
this.issueSign = issueSign;
|
||||
}
|
||||
|
||||
public String getLoginSignData() {
|
||||
return loginSignData;
|
||||
}
|
||||
|
||||
public void setLoginSignData(String loginSignData) {
|
||||
this.loginSignData = loginSignData;
|
||||
}
|
||||
|
||||
public String getLoginSign() {
|
||||
return loginSign;
|
||||
}
|
||||
|
||||
public void setLoginSign(String loginSign) {
|
||||
this.loginSign = loginSign;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,10 @@ public class CurrentUserResponse {
|
||||
private String displayName;
|
||||
@Schema(description = "角色标识", example = "ADMIN")
|
||||
private String role;
|
||||
@Schema(description = "当前会话等级", example = "FULL")
|
||||
private String authLevel;
|
||||
@Schema(description = "是否需要强制修改密码")
|
||||
private Boolean needChangePassword;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
@@ -35,4 +39,20 @@ public class CurrentUserResponse {
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getAuthLevel() {
|
||||
return authLevel;
|
||||
}
|
||||
|
||||
public void setAuthLevel(String authLevel) {
|
||||
this.authLevel = authLevel;
|
||||
}
|
||||
|
||||
public Boolean getNeedChangePassword() {
|
||||
return needChangePassword;
|
||||
}
|
||||
|
||||
public void setNeedChangePassword(Boolean needChangePassword) {
|
||||
this.needChangePassword = needChangePassword;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,28 @@ package com.cisd.tms.modules.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "内部登录请求")
|
||||
public class LoginRequest {
|
||||
|
||||
@NotBlank(message = "username is required")
|
||||
@Schema(description = "登录用户名", example = "admin")
|
||||
private String username;
|
||||
@NotBlank(message = "roleCode is required")
|
||||
@Schema(description = "角色编码", example = "KEY_ADMIN")
|
||||
private String roleCode;
|
||||
|
||||
@NotBlank(message = "password is required")
|
||||
@Schema(description = "登录密码", example = "P@ssw0rd")
|
||||
private String password;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
@Schema(description = "UKey 序列号列表,完整登录时需传入角色要求数量的序列号")
|
||||
private List<@NotBlank(message = "ukey serial must not be blank") String> ukeySerials;
|
||||
|
||||
public String getRoleCode() {
|
||||
return roleCode;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
public void setRoleCode(String roleCode) {
|
||||
this.roleCode = roleCode;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
@@ -29,4 +33,12 @@ public class LoginRequest {
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public List<String> getUkeySerials() {
|
||||
return ukeySerials;
|
||||
}
|
||||
|
||||
public void setUkeySerials(List<String> ukeySerials) {
|
||||
this.ukeySerials = ukeySerials;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,19 +5,23 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@Schema(description = "内部登录响应")
|
||||
public class LoginResponse {
|
||||
|
||||
@Schema(description = "登录用户名", example = "admin")
|
||||
private String username;
|
||||
@Schema(description = "角色编码", example = "KEY_ADMIN")
|
||||
private String roleCode;
|
||||
@Schema(description = "访问令牌")
|
||||
private String token;
|
||||
@Schema(description = "认证等级", example = "FULL")
|
||||
private String authLevel;
|
||||
@Schema(description = "令牌过期时间", example = "2026-03-11T18:00:00+08:00")
|
||||
private String expiresAt;
|
||||
@Schema(description = "是否需要首次修改密码")
|
||||
private Boolean needChangePassword;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
public String getRoleCode() {
|
||||
return roleCode;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
public void setRoleCode(String roleCode) {
|
||||
this.roleCode = roleCode;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
@@ -28,6 +32,14 @@ public class LoginResponse {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getAuthLevel() {
|
||||
return authLevel;
|
||||
}
|
||||
|
||||
public void setAuthLevel(String authLevel) {
|
||||
this.authLevel = authLevel;
|
||||
}
|
||||
|
||||
public String getExpiresAt() {
|
||||
return expiresAt;
|
||||
}
|
||||
@@ -35,4 +47,12 @@ public class LoginResponse {
|
||||
public void setExpiresAt(String expiresAt) {
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
|
||||
public Boolean getNeedChangePassword() {
|
||||
return needChangePassword;
|
||||
}
|
||||
|
||||
public void setNeedChangePassword(Boolean needChangePassword) {
|
||||
this.needChangePassword = needChangePassword;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.cisd.tms.modules.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "UKey 绑定请求")
|
||||
public class UkeyBindRequest {
|
||||
|
||||
@NotNull(message = "slotNo is required")
|
||||
@Schema(description = "角色 UKey 槽位号", example = "1")
|
||||
private Integer slotNo;
|
||||
|
||||
@NotBlank(message = "ukeySerial is required")
|
||||
@Schema(description = "UKey 序列号", example = "UK-001")
|
||||
private String ukeySerial;
|
||||
|
||||
@NotBlank(message = "ukeyPubkey is required")
|
||||
@Schema(description = "UKey 公钥")
|
||||
private String ukeyPubkey;
|
||||
|
||||
@NotBlank(message = "uid is required")
|
||||
@Schema(description = "UKey 认证信息 uid", example = "1")
|
||||
private String uid;
|
||||
|
||||
@NotBlank(message = "rid is required")
|
||||
@Schema(description = "UKey 认证信息 rid", example = "RID-001")
|
||||
private String rid;
|
||||
|
||||
@NotBlank(message = "issuerSign is required")
|
||||
@Schema(description = "认证公钥签名值")
|
||||
private String issuerSign;
|
||||
|
||||
public Integer getSlotNo() {
|
||||
return slotNo;
|
||||
}
|
||||
|
||||
public void setSlotNo(Integer slotNo) {
|
||||
this.slotNo = slotNo;
|
||||
}
|
||||
|
||||
public String getUkeySerial() {
|
||||
return ukeySerial;
|
||||
}
|
||||
|
||||
public void setUkeySerial(String ukeySerial) {
|
||||
this.ukeySerial = ukeySerial;
|
||||
}
|
||||
|
||||
public String getUkeyPubkey() {
|
||||
return ukeyPubkey;
|
||||
}
|
||||
|
||||
public void setUkeyPubkey(String ukeyPubkey) {
|
||||
this.ukeyPubkey = ukeyPubkey;
|
||||
}
|
||||
|
||||
public String getIssuerSign() {
|
||||
return issuerSign;
|
||||
}
|
||||
|
||||
public void setIssuerSign(String issuerSign) {
|
||||
this.issuerSign = issuerSign;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public String getRid() {
|
||||
return rid;
|
||||
}
|
||||
|
||||
public void setRid(String rid) {
|
||||
this.rid = rid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.cisd.tms.modules.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "UKey 登录随机数响应")
|
||||
public class UkeyLoginRandomResponse {
|
||||
|
||||
@Schema(description = "标准化后的角色编码", example = "SUPER_ADMIN")
|
||||
private String roleCode;
|
||||
|
||||
@Schema(description = "供 UKey 登录签名使用的随机数列表")
|
||||
private List<String> randoms;
|
||||
|
||||
public String getRoleCode() {
|
||||
return roleCode;
|
||||
}
|
||||
|
||||
public void setRoleCode(String roleCode) {
|
||||
this.roleCode = roleCode;
|
||||
}
|
||||
|
||||
public List<String> getRandoms() {
|
||||
return randoms;
|
||||
}
|
||||
|
||||
public void setRandoms(List<String> randoms) {
|
||||
this.randoms = randoms;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.cisd.tms.modules.auth.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cisd.tms.infrastructure.persistence.entity.BaseEntity;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@TableName("tms_auth_session")
|
||||
public class AuthSessionEntity extends BaseEntity {
|
||||
|
||||
private String sessionToken;
|
||||
private String roleCode;
|
||||
private String authLevel;
|
||||
private LocalDateTime issuedAt;
|
||||
private LocalDateTime lastActiveAt;
|
||||
private LocalDateTime expiresAt;
|
||||
private LocalDateTime logoutAt;
|
||||
|
||||
public String getSessionToken() {
|
||||
return sessionToken;
|
||||
}
|
||||
|
||||
public void setSessionToken(String sessionToken) {
|
||||
this.sessionToken = sessionToken;
|
||||
}
|
||||
|
||||
public String getRoleCode() {
|
||||
return roleCode;
|
||||
}
|
||||
|
||||
public void setRoleCode(String roleCode) {
|
||||
this.roleCode = roleCode;
|
||||
}
|
||||
|
||||
public String getAuthLevel() {
|
||||
return authLevel;
|
||||
}
|
||||
|
||||
public void setAuthLevel(String authLevel) {
|
||||
this.authLevel = authLevel;
|
||||
}
|
||||
|
||||
public LocalDateTime getIssuedAt() {
|
||||
return issuedAt;
|
||||
}
|
||||
|
||||
public void setIssuedAt(LocalDateTime issuedAt) {
|
||||
this.issuedAt = issuedAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastActiveAt() {
|
||||
return lastActiveAt;
|
||||
}
|
||||
|
||||
public void setLastActiveAt(LocalDateTime lastActiveAt) {
|
||||
this.lastActiveAt = lastActiveAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getExpiresAt() {
|
||||
return expiresAt;
|
||||
}
|
||||
|
||||
public void setExpiresAt(LocalDateTime expiresAt) {
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getLogoutAt() {
|
||||
return logoutAt;
|
||||
}
|
||||
|
||||
public void setLogoutAt(LocalDateTime logoutAt) {
|
||||
this.logoutAt = logoutAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.cisd.tms.modules.auth.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cisd.tms.infrastructure.persistence.entity.BaseEntity;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@TableName("tms_role_account")
|
||||
public class RoleAccountEntity extends BaseEntity {
|
||||
|
||||
private String roleCode;
|
||||
private String displayName;
|
||||
private Integer requiredUkeyCount;
|
||||
private String passwordHash;
|
||||
private String passwordSalt;
|
||||
private String status;
|
||||
private Boolean needChangePassword;
|
||||
private Integer failedCount;
|
||||
private LocalDateTime lockedUntil;
|
||||
private LocalDateTime lastLoginAt;
|
||||
private LocalDateTime lastActiveAt;
|
||||
|
||||
public String getRoleCode() {
|
||||
return roleCode;
|
||||
}
|
||||
|
||||
public void setRoleCode(String roleCode) {
|
||||
this.roleCode = roleCode;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public Integer getRequiredUkeyCount() {
|
||||
return requiredUkeyCount;
|
||||
}
|
||||
|
||||
public void setRequiredUkeyCount(Integer requiredUkeyCount) {
|
||||
this.requiredUkeyCount = requiredUkeyCount;
|
||||
}
|
||||
|
||||
public String getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
public void setPasswordHash(String passwordHash) {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
public String getPasswordSalt() {
|
||||
return passwordSalt;
|
||||
}
|
||||
|
||||
public void setPasswordSalt(String passwordSalt) {
|
||||
this.passwordSalt = passwordSalt;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Boolean getNeedChangePassword() {
|
||||
return needChangePassword;
|
||||
}
|
||||
|
||||
public void setNeedChangePassword(Boolean needChangePassword) {
|
||||
this.needChangePassword = needChangePassword;
|
||||
}
|
||||
|
||||
public Integer getFailedCount() {
|
||||
return failedCount;
|
||||
}
|
||||
|
||||
public void setFailedCount(Integer failedCount) {
|
||||
this.failedCount = failedCount;
|
||||
}
|
||||
|
||||
public LocalDateTime getLockedUntil() {
|
||||
return lockedUntil;
|
||||
}
|
||||
|
||||
public void setLockedUntil(LocalDateTime lockedUntil) {
|
||||
this.lockedUntil = lockedUntil;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastLoginAt() {
|
||||
return lastLoginAt;
|
||||
}
|
||||
|
||||
public void setLastLoginAt(LocalDateTime lastLoginAt) {
|
||||
this.lastLoginAt = lastLoginAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastActiveAt() {
|
||||
return lastActiveAt;
|
||||
}
|
||||
|
||||
public void setLastActiveAt(LocalDateTime lastActiveAt) {
|
||||
this.lastActiveAt = lastActiveAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.cisd.tms.modules.auth.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.cisd.tms.infrastructure.persistence.entity.BaseEntity;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@TableName("tms_role_ukey_binding")
|
||||
public class RoleUkeyBindingEntity extends BaseEntity {
|
||||
|
||||
private String roleCode;
|
||||
private Integer slotNo;
|
||||
private String ukeySerial;
|
||||
private String ukeyPubkey;
|
||||
private String issuerSign;
|
||||
private String status;
|
||||
private LocalDateTime boundAt;
|
||||
private LocalDateTime unboundAt;
|
||||
|
||||
public String getRoleCode() {
|
||||
return roleCode;
|
||||
}
|
||||
|
||||
public void setRoleCode(String roleCode) {
|
||||
this.roleCode = roleCode;
|
||||
}
|
||||
|
||||
public Integer getSlotNo() {
|
||||
return slotNo;
|
||||
}
|
||||
|
||||
public void setSlotNo(Integer slotNo) {
|
||||
this.slotNo = slotNo;
|
||||
}
|
||||
|
||||
public String getUkeySerial() {
|
||||
return ukeySerial;
|
||||
}
|
||||
|
||||
public void setUkeySerial(String ukeySerial) {
|
||||
this.ukeySerial = ukeySerial;
|
||||
}
|
||||
|
||||
public String getUkeyPubkey() {
|
||||
return ukeyPubkey;
|
||||
}
|
||||
|
||||
public void setUkeyPubkey(String ukeyPubkey) {
|
||||
this.ukeyPubkey = ukeyPubkey;
|
||||
}
|
||||
|
||||
public String getIssuerSign() {
|
||||
return issuerSign;
|
||||
}
|
||||
|
||||
public void setIssuerSign(String issuerSign) {
|
||||
this.issuerSign = issuerSign;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDateTime getBoundAt() {
|
||||
return boundAt;
|
||||
}
|
||||
|
||||
public void setBoundAt(LocalDateTime boundAt) {
|
||||
this.boundAt = boundAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUnboundAt() {
|
||||
return unboundAt;
|
||||
}
|
||||
|
||||
public void setUnboundAt(LocalDateTime unboundAt) {
|
||||
this.unboundAt = unboundAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.cisd.tms.modules.auth.enums;
|
||||
|
||||
public enum AuthLevel {
|
||||
LIMITED,
|
||||
FULL
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cisd.tms.modules.auth.enums;
|
||||
|
||||
public enum RoleAccountStatus {
|
||||
UNENABLED,
|
||||
ACTIVE,
|
||||
LOCKED
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.cisd.tms.modules.auth.enums;
|
||||
|
||||
public enum RoleCode {
|
||||
SUPER_ADMIN("SUPER_ADMIN", "超级管理员", 3),
|
||||
KEY_ADMIN("KEY_ADMIN", "密钥管理员", 2),
|
||||
AUDIT_ADMIN("AUDIT_ADMIN", "审计管理员", 1),
|
||||
OPS_ADMIN("OPS_ADMIN", "运维管理员", 1);
|
||||
|
||||
private final String code;
|
||||
private final String displayName;
|
||||
private final int requiredUkeyCount;
|
||||
|
||||
RoleCode(String code, String displayName, int requiredUkeyCount) {
|
||||
this.code = code;
|
||||
this.displayName = displayName;
|
||||
this.requiredUkeyCount = requiredUkeyCount;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public int getRequiredUkeyCount() {
|
||||
return requiredUkeyCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.cisd.tms.modules.auth.mapper;
|
||||
|
||||
import com.cisd.tms.infrastructure.persistence.mapper.BaseMapperX;
|
||||
import com.cisd.tms.modules.auth.entity.AuthSessionEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface AuthSessionMapper extends BaseMapperX<AuthSessionEntity> {
|
||||
|
||||
AuthSessionEntity selectBySessionToken(@Param("sessionToken") String sessionToken);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.cisd.tms.modules.auth.mapper;
|
||||
|
||||
import com.cisd.tms.infrastructure.persistence.mapper.BaseMapperX;
|
||||
import com.cisd.tms.modules.auth.entity.RoleAccountEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface RoleAccountMapper extends BaseMapperX<RoleAccountEntity> {
|
||||
|
||||
RoleAccountEntity selectByRoleCode(@Param("roleCode") String roleCode);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.cisd.tms.modules.auth.mapper;
|
||||
|
||||
import com.cisd.tms.infrastructure.persistence.mapper.BaseMapperX;
|
||||
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface RoleUkeyBindingMapper extends BaseMapperX<RoleUkeyBindingEntity> {
|
||||
|
||||
RoleUkeyBindingEntity selectActiveByRoleCodeAndSlotNo(@Param("roleCode") String roleCode, @Param("slotNo") Integer slotNo);
|
||||
|
||||
List<RoleUkeyBindingEntity> selectActiveByRoleCode(@Param("roleCode") String roleCode);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.cisd.tms.modules.auth.repository;
|
||||
|
||||
import com.cisd.tms.modules.auth.entity.AuthSessionEntity;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface AuthSessionRepository {
|
||||
|
||||
Optional<AuthSessionEntity> findBySessionToken(String sessionToken);
|
||||
|
||||
void save(AuthSessionEntity entity);
|
||||
|
||||
void update(AuthSessionEntity entity);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.cisd.tms.modules.auth.repository;
|
||||
|
||||
import com.cisd.tms.modules.auth.entity.RoleAccountEntity;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface RoleAccountRepository {
|
||||
|
||||
Optional<RoleAccountEntity> findByRoleCode(String roleCode);
|
||||
|
||||
void save(RoleAccountEntity entity);
|
||||
|
||||
void update(RoleAccountEntity entity);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.cisd.tms.modules.auth.repository;
|
||||
|
||||
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface RoleUkeyBindingRepository {
|
||||
|
||||
Optional<RoleUkeyBindingEntity> findActiveByRoleCodeAndSlotNo(String roleCode, Integer slotNo);
|
||||
|
||||
List<RoleUkeyBindingEntity> findActiveByRoleCode(String roleCode);
|
||||
|
||||
void save(RoleUkeyBindingEntity entity);
|
||||
|
||||
void update(RoleUkeyBindingEntity entity);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.cisd.tms.modules.auth.repository.impl;
|
||||
|
||||
import com.cisd.tms.modules.auth.entity.AuthSessionEntity;
|
||||
import com.cisd.tms.modules.auth.mapper.AuthSessionMapper;
|
||||
import com.cisd.tms.modules.auth.repository.AuthSessionRepository;
|
||||
import java.util.Optional;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public class AuthSessionRepositoryImpl implements AuthSessionRepository {
|
||||
|
||||
private final AuthSessionMapper authSessionMapper;
|
||||
|
||||
public AuthSessionRepositoryImpl(AuthSessionMapper authSessionMapper) {
|
||||
this.authSessionMapper = authSessionMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AuthSessionEntity> findBySessionToken(String sessionToken) {
|
||||
return Optional.ofNullable(authSessionMapper.selectBySessionToken(sessionToken));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(AuthSessionEntity entity) {
|
||||
authSessionMapper.insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AuthSessionEntity entity) {
|
||||
authSessionMapper.updateById(entity);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.cisd.tms.modules.auth.repository.impl;
|
||||
|
||||
import com.cisd.tms.modules.auth.entity.RoleAccountEntity;
|
||||
import com.cisd.tms.modules.auth.mapper.RoleAccountMapper;
|
||||
import com.cisd.tms.modules.auth.repository.RoleAccountRepository;
|
||||
import java.util.Optional;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public class RoleAccountRepositoryImpl implements RoleAccountRepository {
|
||||
|
||||
private final RoleAccountMapper roleAccountMapper;
|
||||
|
||||
public RoleAccountRepositoryImpl(RoleAccountMapper roleAccountMapper) {
|
||||
this.roleAccountMapper = roleAccountMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RoleAccountEntity> findByRoleCode(String roleCode) {
|
||||
return Optional.ofNullable(roleAccountMapper.selectByRoleCode(roleCode));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(RoleAccountEntity entity) {
|
||||
roleAccountMapper.insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(RoleAccountEntity entity) {
|
||||
roleAccountMapper.updateById(entity);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.cisd.tms.modules.auth.repository.impl;
|
||||
|
||||
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
|
||||
import com.cisd.tms.modules.auth.mapper.RoleUkeyBindingMapper;
|
||||
import com.cisd.tms.modules.auth.repository.RoleUkeyBindingRepository;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public class RoleUkeyBindingRepositoryImpl implements RoleUkeyBindingRepository {
|
||||
|
||||
private final RoleUkeyBindingMapper roleUkeyBindingMapper;
|
||||
|
||||
public RoleUkeyBindingRepositoryImpl(RoleUkeyBindingMapper roleUkeyBindingMapper) {
|
||||
this.roleUkeyBindingMapper = roleUkeyBindingMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RoleUkeyBindingEntity> findActiveByRoleCodeAndSlotNo(String roleCode, Integer slotNo) {
|
||||
return Optional.ofNullable(roleUkeyBindingMapper.selectActiveByRoleCodeAndSlotNo(roleCode, slotNo));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleUkeyBindingEntity> findActiveByRoleCode(String roleCode) {
|
||||
return roleUkeyBindingMapper.selectActiveByRoleCode(roleCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(RoleUkeyBindingEntity entity) {
|
||||
roleUkeyBindingMapper.insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(RoleUkeyBindingEntity entity) {
|
||||
roleUkeyBindingMapper.updateById(entity);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.cisd.tms.modules.auth.security;
|
||||
|
||||
import com.cisd.tms.common.api.ApiResponse;
|
||||
import com.cisd.tms.common.enums.ErrorCode;
|
||||
import com.cisd.tms.common.util.HttpResponseUtil;
|
||||
import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
@Component
|
||||
public class InternalAuthorizationInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public InternalAuthorizationInterceptor(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
if (!(handler instanceof HandlerMethod handlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RequireRole requireRole = findAnnotation(handlerMethod, RequireRole.class);
|
||||
if (requireRole != null) {
|
||||
String currentRole = (String) request.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE);
|
||||
if (!requireRole.value().equals(currentRole)) {
|
||||
writeForbidden(response, "role not allowed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RequireAuthLevel requireAuthLevel = findAnnotation(handlerMethod, RequireAuthLevel.class);
|
||||
if (requireAuthLevel != null) {
|
||||
String currentAuthLevel = (String) request.getAttribute(InternalApiAuthInterceptor.ATTR_AUTH_LEVEL);
|
||||
if (!requireAuthLevel.value().equals(currentAuthLevel)) {
|
||||
writeForbidden(response, "auth level not allowed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private <T extends java.lang.annotation.Annotation> T findAnnotation(HandlerMethod handlerMethod, Class<T> annotationType) {
|
||||
T methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(handlerMethod.getMethod(), annotationType);
|
||||
if (methodAnnotation != null) {
|
||||
return methodAnnotation;
|
||||
}
|
||||
return AnnotatedElementUtils.findMergedAnnotation(handlerMethod.getBeanType(), annotationType);
|
||||
}
|
||||
|
||||
private void writeForbidden(HttpServletResponse response, String message) throws IOException {
|
||||
HttpResponseUtil.writeJson(
|
||||
response,
|
||||
HttpServletResponse.SC_FORBIDDEN,
|
||||
ApiResponse.fail(ErrorCode.UNAUTHORIZED.getCode(), message),
|
||||
objectMapper
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.cisd.tms.modules.auth.security;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface RequireAuthLevel {
|
||||
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.cisd.tms.modules.auth.security;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface RequireRole {
|
||||
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
import com.cisd.tms.common.enums.ErrorCode;
|
||||
import com.cisd.tms.common.exception.BizException;
|
||||
import com.cisd.tms.integration.crypto.pcie.service.MockPcieCryptoService;
|
||||
import com.cisd.tms.modules.auth.entity.RoleAccountEntity;
|
||||
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
|
||||
import com.cisd.tms.modules.auth.enums.AuthLevel;
|
||||
import com.cisd.tms.modules.auth.enums.RoleAccountStatus;
|
||||
import com.cisd.tms.modules.auth.enums.RoleCode;
|
||||
import com.cisd.tms.modules.auth.repository.RoleAccountRepository;
|
||||
import com.cisd.tms.modules.auth.repository.RoleUkeyBindingRepository;
|
||||
import com.cisd.tms.common.util.TraceIdUtil;
|
||||
import com.cisd.tms.modules.mk.config.MasterKeyInitProperties;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignDTO;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignEntity;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignResult;
|
||||
import com.cisd.tms.modules.mk.service.LmkService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AuthAdminService {
|
||||
|
||||
static final String DEFAULT_PASSWORD = "12345678";
|
||||
|
||||
private final RoleAccountRepository roleAccountRepository;
|
||||
private final RoleUkeyBindingRepository roleUkeyBindingRepository;
|
||||
private final PasswordHasher passwordHasher;
|
||||
private final LmkService lmkService;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final Clock clock;
|
||||
private final Supplier<String> saltSupplier;
|
||||
|
||||
@Autowired
|
||||
public AuthAdminService(
|
||||
RoleAccountRepository roleAccountRepository,
|
||||
RoleUkeyBindingRepository roleUkeyBindingRepository,
|
||||
PasswordHasher passwordHasher,
|
||||
LmkService lmkService,
|
||||
ObjectMapper objectMapper
|
||||
) {
|
||||
this(
|
||||
roleAccountRepository,
|
||||
roleUkeyBindingRepository,
|
||||
passwordHasher,
|
||||
lmkService,
|
||||
objectMapper,
|
||||
Clock.systemUTC(),
|
||||
() -> UUID.randomUUID().toString().replace("-", "")
|
||||
);
|
||||
}
|
||||
|
||||
AuthAdminService(
|
||||
RoleAccountRepository roleAccountRepository,
|
||||
RoleUkeyBindingRepository roleUkeyBindingRepository,
|
||||
LmkService lmkService,
|
||||
PasswordHasher passwordHasher,
|
||||
Clock clock,
|
||||
Supplier<String> saltSupplier
|
||||
) {
|
||||
this(
|
||||
roleAccountRepository,
|
||||
roleUkeyBindingRepository,
|
||||
passwordHasher,
|
||||
lmkService,
|
||||
new ObjectMapper(),
|
||||
clock,
|
||||
saltSupplier
|
||||
);
|
||||
}
|
||||
|
||||
AuthAdminService(
|
||||
RoleAccountRepository roleAccountRepository,
|
||||
RoleUkeyBindingRepository roleUkeyBindingRepository,
|
||||
PasswordHasher passwordHasher,
|
||||
Clock clock,
|
||||
Supplier<String> saltSupplier
|
||||
) {
|
||||
this(
|
||||
roleAccountRepository,
|
||||
roleUkeyBindingRepository,
|
||||
new LmkService(new MockPcieCryptoService(), new MasterKeyInitProperties()),
|
||||
passwordHasher,
|
||||
clock,
|
||||
saltSupplier
|
||||
);
|
||||
}
|
||||
|
||||
AuthAdminService(
|
||||
RoleAccountRepository roleAccountRepository,
|
||||
RoleUkeyBindingRepository roleUkeyBindingRepository,
|
||||
PasswordHasher passwordHasher,
|
||||
LmkService lmkService,
|
||||
ObjectMapper objectMapper,
|
||||
Clock clock,
|
||||
Supplier<String> saltSupplier
|
||||
) {
|
||||
this.roleAccountRepository = roleAccountRepository;
|
||||
this.roleUkeyBindingRepository = roleUkeyBindingRepository;
|
||||
this.passwordHasher = passwordHasher;
|
||||
this.lmkService = lmkService;
|
||||
this.objectMapper = objectMapper;
|
||||
this.clock = clock;
|
||||
this.saltSupplier = saltSupplier;
|
||||
}
|
||||
|
||||
public void enableRole(String operatorRoleCode, String operatorAuthLevel, String targetRoleCode) {
|
||||
requireKeyAdminFull(operatorRoleCode, operatorAuthLevel);
|
||||
RoleAccountEntity target = loadRole(targetRoleCode);
|
||||
target.setStatus(RoleAccountStatus.ACTIVE.name());
|
||||
target.setNeedChangePassword(Boolean.TRUE);
|
||||
target.setLockedUntil(null);
|
||||
target.setFailedCount(0);
|
||||
roleAccountRepository.update(target);
|
||||
}
|
||||
|
||||
public void resetPassword(String operatorRoleCode, String operatorAuthLevel, String targetRoleCode) {
|
||||
requireKeyAdminFull(operatorRoleCode, operatorAuthLevel);
|
||||
RoleAccountEntity target = loadRole(targetRoleCode);
|
||||
String newSalt = saltSupplier.get();
|
||||
target.setPasswordSalt(newSalt);
|
||||
target.setPasswordHash(passwordHasher.hash(DEFAULT_PASSWORD, newSalt));
|
||||
target.setStatus(RoleAccountStatus.ACTIVE.name());
|
||||
target.setNeedChangePassword(Boolean.TRUE);
|
||||
target.setFailedCount(0);
|
||||
target.setLockedUntil(null);
|
||||
roleAccountRepository.update(target);
|
||||
}
|
||||
|
||||
public void bindUkey(
|
||||
String operatorRoleCode,
|
||||
String operatorAuthLevel,
|
||||
String targetRoleCode,
|
||||
Integer slotNo,
|
||||
String ukeySerial,
|
||||
String ukeyPubkey,
|
||||
String issuerSign
|
||||
) {
|
||||
requireKeyAdminFull(operatorRoleCode, operatorAuthLevel);
|
||||
RoleCode targetRole = resolveRoleCode(targetRoleCode);
|
||||
if (slotNo == null || slotNo < 1 || slotNo > targetRole.getRequiredUkeyCount()) {
|
||||
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "slotNo exceeds role ukey requirement");
|
||||
}
|
||||
|
||||
RoleUkeyBindingEntity binding = roleUkeyBindingRepository
|
||||
.findActiveByRoleCodeAndSlotNo(targetRoleCode, slotNo)
|
||||
.orElseGet(RoleUkeyBindingEntity::new);
|
||||
if (binding.getId() == null) {
|
||||
binding.setId((long) Math.abs(Objects.hash(targetRoleCode, slotNo, ukeySerial, TraceIdUtil.newTraceId())));
|
||||
binding.setRoleCode(targetRoleCode);
|
||||
binding.setSlotNo(slotNo);
|
||||
binding.setStatus("ACTIVE");
|
||||
applyBinding(binding, ukeySerial, ukeyPubkey, issuerSign);
|
||||
roleUkeyBindingRepository.save(binding);
|
||||
return;
|
||||
}
|
||||
|
||||
applyBinding(binding, ukeySerial, ukeyPubkey, issuerSign);
|
||||
roleUkeyBindingRepository.update(binding);
|
||||
}
|
||||
|
||||
public void bindIssuedUkey(
|
||||
String operatorRoleCode,
|
||||
String operatorAuthLevel,
|
||||
String targetRoleCode,
|
||||
Integer slotNo,
|
||||
String ukeySerial,
|
||||
String ukeyPubkey,
|
||||
String uid,
|
||||
String rid,
|
||||
String issuerSign
|
||||
) {
|
||||
requireKeyAdminFull(operatorRoleCode, operatorAuthLevel);
|
||||
resolveRoleCode(targetRoleCode);
|
||||
verifyIssuerSignature(targetRoleCode, ukeyPubkey, uid, rid, issuerSign);
|
||||
bindUkey(operatorRoleCode, operatorAuthLevel, targetRoleCode, slotNo, ukeySerial, ukeyPubkey, issuerSign);
|
||||
}
|
||||
|
||||
public UKeySignResult issueUkeyBindingSign(
|
||||
String operatorRoleCode,
|
||||
String operatorAuthLevel,
|
||||
String targetRoleCode,
|
||||
UKeySignDTO request
|
||||
) {
|
||||
requireKeyAdminFull(operatorRoleCode, operatorAuthLevel);
|
||||
RoleCode targetRole = resolveRoleCode(targetRoleCode);
|
||||
String legacyRole = toLegacyRole(targetRole);
|
||||
String authKeyPair = lmkService.exportIkPublicKeyHex();
|
||||
|
||||
UKeySignDTO dto = new UKeySignDTO();
|
||||
dto.setPubKey(request.getPubKey());
|
||||
dto.setRole(legacyRole);
|
||||
dto.setUid(request.getUid());
|
||||
dto.setRid(request.getRid());
|
||||
dto.setExtra(request.getExtra());
|
||||
|
||||
String signValue = lmkService.signIk(toIssuePayload(dto, authKeyPair));
|
||||
String extra = "";
|
||||
return UKeySignResult.builder().sign(signValue).component(extra).build();
|
||||
}
|
||||
|
||||
private void applyBinding(RoleUkeyBindingEntity binding, String ukeySerial, String ukeyPubkey, String issuerSign) {
|
||||
binding.setUkeySerial(ukeySerial);
|
||||
binding.setUkeyPubkey(ukeyPubkey);
|
||||
binding.setIssuerSign(issuerSign);
|
||||
binding.setStatus("ACTIVE");
|
||||
binding.setBoundAt(now());
|
||||
binding.setUnboundAt(null);
|
||||
}
|
||||
|
||||
private void requireKeyAdminFull(String operatorRoleCode, String operatorAuthLevel) {
|
||||
if (!RoleCode.KEY_ADMIN.getCode().equals(operatorRoleCode) || !AuthLevel.FULL.name().equals(operatorAuthLevel)) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "operation requires KEY_ADMIN FULL session");
|
||||
}
|
||||
}
|
||||
|
||||
private RoleAccountEntity loadRole(String roleCode) {
|
||||
resolveRoleCode(roleCode);
|
||||
return roleAccountRepository.findByRoleCode(roleCode)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "target role account not found"));
|
||||
}
|
||||
|
||||
private RoleCode resolveRoleCode(String roleCode) {
|
||||
return List.of(RoleCode.values()).stream()
|
||||
.filter(item -> item.getCode().equals(roleCode))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "invalid roleCode"));
|
||||
}
|
||||
|
||||
private LocalDateTime now() {
|
||||
return LocalDateTime.ofInstant(clock.instant(), ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
private void verifyIssuerSignature(String targetRoleCode, String ukeyPubkey, String uid, String rid, String issuerSign) {
|
||||
try {
|
||||
UKeySignDTO dto = new UKeySignDTO();
|
||||
dto.setPubKey(ukeyPubkey);
|
||||
dto.setRole(toLegacyRole(resolveRoleCode(targetRoleCode)));
|
||||
dto.setUid(uid);
|
||||
dto.setRid(rid);
|
||||
String authKeyPair = lmkService.exportIkPublicKeyHex();
|
||||
lmkService.verifyIk(toIssuePayload(dto, authKeyPair), issuerSign);
|
||||
} catch (BizException ex) {
|
||||
throw ex;
|
||||
} catch (RuntimeException ex) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "ukey issuer signature verification failed");
|
||||
}
|
||||
}
|
||||
|
||||
private String toIssuePayload(UKeySignDTO dto, String authKeyPair) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(UKeySignEntity.getInstance(dto, authKeyPair));
|
||||
} catch (JsonProcessingException ex) {
|
||||
throw new IllegalStateException("serialize ukey issue payload failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String toLegacyRole(RoleCode roleCode) {
|
||||
return switch (roleCode) {
|
||||
case SUPER_ADMIN -> "superadmin";
|
||||
case KEY_ADMIN -> "keyadmin";
|
||||
case AUDIT_ADMIN -> "auditadmin";
|
||||
case OPS_ADMIN -> "configadmin";
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,126 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
import com.cisd.tms.common.enums.ErrorCode;
|
||||
import com.cisd.tms.common.exception.BizException;
|
||||
import com.cisd.tms.modules.auth.dto.CurrentUserResponse;
|
||||
import com.cisd.tms.modules.auth.dto.LoginRequest;
|
||||
import com.cisd.tms.modules.auth.dto.LoginResponse;
|
||||
import com.cisd.tms.modules.auth.entity.AuthSessionEntity;
|
||||
import com.cisd.tms.modules.auth.entity.AuthUserEntity;
|
||||
import com.cisd.tms.modules.auth.entity.RoleAccountEntity;
|
||||
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
|
||||
import com.cisd.tms.modules.auth.enums.AuthLevel;
|
||||
import com.cisd.tms.modules.auth.enums.RoleAccountStatus;
|
||||
import com.cisd.tms.modules.auth.repository.AuthUserRepository;
|
||||
import com.cisd.tms.modules.auth.repository.AuthSessionRepository;
|
||||
import com.cisd.tms.modules.auth.repository.RoleAccountRepository;
|
||||
import com.cisd.tms.modules.auth.repository.RoleUkeyBindingRepository;
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AuthService {
|
||||
|
||||
private final AuthUserRepository authUserRepository;
|
||||
private static final int MAX_FAILED_ATTEMPTS = 5;
|
||||
private static final int IDLE_TIMEOUT_MINUTES = 10;
|
||||
|
||||
public AuthService(AuthUserRepository authUserRepository) {
|
||||
private final RoleAccountRepository roleAccountRepository;
|
||||
private final AuthUserRepository authUserRepository;
|
||||
private final AuthSessionRepository authSessionRepository;
|
||||
private final RoleUkeyBindingRepository roleUkeyBindingRepository;
|
||||
private final PasswordHasher passwordHasher;
|
||||
private final Clock clock;
|
||||
private final Supplier<String> tokenSupplier;
|
||||
|
||||
@Autowired
|
||||
public AuthService(
|
||||
RoleAccountRepository roleAccountRepository,
|
||||
AuthUserRepository authUserRepository,
|
||||
AuthSessionRepository authSessionRepository,
|
||||
RoleUkeyBindingRepository roleUkeyBindingRepository,
|
||||
PasswordHasher passwordHasher
|
||||
) {
|
||||
this(
|
||||
roleAccountRepository,
|
||||
authUserRepository,
|
||||
authSessionRepository,
|
||||
roleUkeyBindingRepository,
|
||||
passwordHasher,
|
||||
Clock.systemUTC(),
|
||||
() -> "tms-" + UUID.randomUUID()
|
||||
);
|
||||
}
|
||||
|
||||
AuthService(
|
||||
RoleAccountRepository roleAccountRepository,
|
||||
AuthUserRepository authUserRepository,
|
||||
AuthSessionRepository authSessionRepository,
|
||||
RoleUkeyBindingRepository roleUkeyBindingRepository,
|
||||
PasswordHasher passwordHasher,
|
||||
Clock clock,
|
||||
Supplier<String> tokenSupplier
|
||||
) {
|
||||
this.roleAccountRepository = roleAccountRepository;
|
||||
this.authUserRepository = authUserRepository;
|
||||
this.authSessionRepository = authSessionRepository;
|
||||
this.roleUkeyBindingRepository = roleUkeyBindingRepository;
|
||||
this.passwordHasher = passwordHasher;
|
||||
this.clock = clock;
|
||||
this.tokenSupplier = tokenSupplier;
|
||||
}
|
||||
|
||||
public LoginResponse login(LoginRequest request) {
|
||||
RoleAccountEntity roleAccount = roleAccountRepository.findByRoleCode(request.getRoleCode())
|
||||
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "role account not found"));
|
||||
|
||||
validateRoleStatus(roleAccount);
|
||||
if (!passwordHasher.matches(request.getPassword(), roleAccount.getPasswordSalt(), roleAccount.getPasswordHash())) {
|
||||
onPasswordFailed(roleAccount);
|
||||
}
|
||||
|
||||
resetFailureState(roleAccount);
|
||||
AuthLevel authLevel = resolveAuthLevel(roleAccount, request.getUkeySerials());
|
||||
AuthSessionEntity session = buildSession(roleAccount.getRoleCode(), authLevel);
|
||||
authSessionRepository.save(session);
|
||||
|
||||
LoginResponse response = new LoginResponse();
|
||||
response.setUsername(request.getUsername());
|
||||
response.setToken("tms-" + UUID.randomUUID());
|
||||
response.setExpiresAt(OffsetDateTime.now().plusHours(8).toString());
|
||||
response.setRoleCode(roleAccount.getRoleCode());
|
||||
response.setAuthLevel(authLevel.name());
|
||||
response.setToken(session.getSessionToken());
|
||||
response.setExpiresAt(OffsetDateTime.of(session.getExpiresAt(), ZoneOffset.UTC).toString());
|
||||
response.setNeedChangePassword(Boolean.TRUE.equals(roleAccount.getNeedChangePassword()));
|
||||
return response;
|
||||
}
|
||||
|
||||
public CurrentUserResponse me(String username) {
|
||||
return me(username, null);
|
||||
}
|
||||
|
||||
public CurrentUserResponse me(String username, String sessionToken) {
|
||||
String normalized = username == null || username.isBlank() ? "admin" : username;
|
||||
RoleAccountEntity roleAccount = roleAccountRepository.findByRoleCode(normalized).orElse(null);
|
||||
if (roleAccount != null) {
|
||||
CurrentUserResponse response = new CurrentUserResponse();
|
||||
response.setUsername(roleAccount.getRoleCode());
|
||||
response.setDisplayName(roleAccount.getDisplayName());
|
||||
response.setRole(roleAccount.getRoleCode());
|
||||
AuthSessionEntity session = sessionToken == null ? null : authSessionRepository.findBySessionToken(sessionToken).orElse(null);
|
||||
if (session != null) {
|
||||
response.setAuthLevel(session.getAuthLevel());
|
||||
}
|
||||
response.setNeedChangePassword(Boolean.TRUE.equals(roleAccount.getNeedChangePassword()));
|
||||
return response;
|
||||
}
|
||||
|
||||
AuthUserEntity entity = authUserRepository.findByUsername(normalized).orElse(null);
|
||||
|
||||
CurrentUserResponse response = new CurrentUserResponse();
|
||||
@@ -43,4 +136,114 @@ public class AuthService {
|
||||
response.setRole(entity.getRole());
|
||||
return response;
|
||||
}
|
||||
|
||||
public void logout(String sessionToken) {
|
||||
AuthSessionEntity session = requireActiveSession(sessionToken);
|
||||
session.setLogoutAt(now());
|
||||
session.setExpiresAt(now());
|
||||
authSessionRepository.update(session);
|
||||
}
|
||||
|
||||
public void changePassword(String sessionToken, String currentPassword, String newPassword) {
|
||||
AuthSessionEntity session = requireActiveSession(sessionToken);
|
||||
RoleAccountEntity roleAccount = roleAccountRepository.findByRoleCode(session.getRoleCode())
|
||||
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "role account not found"));
|
||||
if (!passwordHasher.matches(currentPassword, roleAccount.getPasswordSalt(), roleAccount.getPasswordHash())) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "current password is incorrect");
|
||||
}
|
||||
|
||||
String newSalt = UUID.randomUUID().toString().replace("-", "");
|
||||
roleAccount.setPasswordSalt(newSalt);
|
||||
roleAccount.setPasswordHash(passwordHasher.hash(newPassword, newSalt));
|
||||
roleAccount.setNeedChangePassword(Boolean.FALSE);
|
||||
roleAccount.setFailedCount(0);
|
||||
roleAccount.setLockedUntil(null);
|
||||
roleAccount.setStatus(RoleAccountStatus.ACTIVE.name());
|
||||
roleAccountRepository.update(roleAccount);
|
||||
}
|
||||
|
||||
private void validateRoleStatus(RoleAccountEntity roleAccount) {
|
||||
if (RoleAccountStatus.UNENABLED.name().equals(roleAccount.getStatus())) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "role is not enabled");
|
||||
}
|
||||
if (RoleAccountStatus.LOCKED.name().equals(roleAccount.getStatus()) && isStillLocked(roleAccount)) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "role account is locked");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isStillLocked(RoleAccountEntity roleAccount) {
|
||||
return roleAccount.getLockedUntil() == null || roleAccount.getLockedUntil().isAfter(now());
|
||||
}
|
||||
|
||||
private void onPasswordFailed(RoleAccountEntity roleAccount) {
|
||||
int failedCount = roleAccount.getFailedCount() == null ? 0 : roleAccount.getFailedCount();
|
||||
failedCount++;
|
||||
roleAccount.setFailedCount(failedCount);
|
||||
if (failedCount >= MAX_FAILED_ATTEMPTS) {
|
||||
roleAccount.setStatus(RoleAccountStatus.LOCKED.name());
|
||||
roleAccount.setLockedUntil(now().plusMinutes(IDLE_TIMEOUT_MINUTES));
|
||||
roleAccountRepository.update(roleAccount);
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "role account is locked");
|
||||
}
|
||||
roleAccountRepository.update(roleAccount);
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "password is incorrect");
|
||||
}
|
||||
|
||||
private void resetFailureState(RoleAccountEntity roleAccount) {
|
||||
roleAccount.setFailedCount(0);
|
||||
roleAccount.setLockedUntil(null);
|
||||
roleAccount.setStatus(RoleAccountStatus.ACTIVE.name());
|
||||
roleAccount.setLastLoginAt(now());
|
||||
roleAccount.setLastActiveAt(now());
|
||||
roleAccountRepository.update(roleAccount);
|
||||
}
|
||||
|
||||
private AuthLevel resolveAuthLevel(RoleAccountEntity roleAccount, List<String> ukeySerials) {
|
||||
if (ukeySerials == null || ukeySerials.isEmpty()) {
|
||||
return AuthLevel.LIMITED;
|
||||
}
|
||||
|
||||
Set<String> uniqueSerials = new LinkedHashSet<>(ukeySerials);
|
||||
if (uniqueSerials.size() != roleAccount.getRequiredUkeyCount()) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "ukey count does not satisfy role requirement");
|
||||
}
|
||||
|
||||
List<RoleUkeyBindingEntity> bindings = roleUkeyBindingRepository.findActiveByRoleCode(roleAccount.getRoleCode());
|
||||
if (bindings.size() != roleAccount.getRequiredUkeyCount()) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "ukey count does not satisfy role requirement");
|
||||
}
|
||||
|
||||
Set<String> boundSerials = bindings.stream()
|
||||
.map(RoleUkeyBindingEntity::getUkeySerial)
|
||||
.collect(java.util.stream.Collectors.toSet());
|
||||
if (!boundSerials.containsAll(uniqueSerials)) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "ukey verification failed");
|
||||
}
|
||||
return AuthLevel.FULL;
|
||||
}
|
||||
|
||||
private AuthSessionEntity buildSession(String roleCode, AuthLevel authLevel) {
|
||||
LocalDateTime issuedAt = now();
|
||||
AuthSessionEntity entity = new AuthSessionEntity();
|
||||
entity.setRoleCode(roleCode);
|
||||
entity.setAuthLevel(authLevel.name());
|
||||
entity.setSessionToken(tokenSupplier.get());
|
||||
entity.setIssuedAt(issuedAt);
|
||||
entity.setLastActiveAt(issuedAt);
|
||||
entity.setExpiresAt(issuedAt.plusMinutes(IDLE_TIMEOUT_MINUTES));
|
||||
return entity;
|
||||
}
|
||||
|
||||
private LocalDateTime now() {
|
||||
return LocalDateTime.ofInstant(clock.instant(), ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
private AuthSessionEntity requireActiveSession(String sessionToken) {
|
||||
AuthSessionEntity session = authSessionRepository.findBySessionToken(sessionToken)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "session not found"));
|
||||
if (session.getLogoutAt() != null || session.getExpiresAt() == null || !session.getExpiresAt().isAfter(now())) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "session expired");
|
||||
}
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
import com.cisd.tms.common.enums.ErrorCode;
|
||||
import com.cisd.tms.common.exception.BizException;
|
||||
import com.cisd.tms.modules.auth.dto.CompatPasswordLoginRequest;
|
||||
import com.cisd.tms.modules.auth.dto.CompatUkeyLoginRequest;
|
||||
import com.cisd.tms.modules.auth.dto.LoginRequest;
|
||||
import com.cisd.tms.modules.auth.dto.LoginResponse;
|
||||
import com.cisd.tms.modules.auth.dto.UkeyLoginRandomResponse;
|
||||
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
|
||||
import com.cisd.tms.modules.auth.enums.RoleCode;
|
||||
import com.cisd.tms.modules.auth.repository.RoleUkeyBindingRepository;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignDTO;
|
||||
import com.cisd.tms.modules.mk.dto.UKeySignEntity;
|
||||
import com.cisd.tms.modules.mk.enums.MasterKeyStatus;
|
||||
import com.cisd.tms.modules.mk.service.LmkService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CompatAuthService {
|
||||
|
||||
private final AuthService authService;
|
||||
private final RoleUkeyBindingRepository roleUkeyBindingRepository;
|
||||
private final LmkService lmkService;
|
||||
private final UkeyLoginRandomService ukeyLoginRandomService;
|
||||
private final CompatUkeyVerifier compatUkeyVerifier;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public CompatAuthService(
|
||||
AuthService authService,
|
||||
RoleUkeyBindingRepository roleUkeyBindingRepository,
|
||||
LmkService lmkService,
|
||||
UkeyLoginRandomService ukeyLoginRandomService,
|
||||
CompatUkeyVerifier compatUkeyVerifier,
|
||||
ObjectMapper objectMapper
|
||||
) {
|
||||
this.authService = authService;
|
||||
this.roleUkeyBindingRepository = roleUkeyBindingRepository;
|
||||
this.lmkService = lmkService;
|
||||
this.ukeyLoginRandomService = ukeyLoginRandomService;
|
||||
this.compatUkeyVerifier = compatUkeyVerifier;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
public UkeyLoginRandomResponse issueUkeyLoginRandoms(String legacyRole, Integer count) {
|
||||
RoleCode roleCode = resolveRoleCode(legacyRole);
|
||||
int resolvedCount = count == null ? roleCode.getRequiredUkeyCount() : count;
|
||||
UkeyLoginRandomResponse response = new UkeyLoginRandomResponse();
|
||||
response.setRoleCode(roleCode.getCode());
|
||||
response.setRandoms(ukeyLoginRandomService.issue(roleCode.getCode(), resolvedCount));
|
||||
return response;
|
||||
}
|
||||
|
||||
public LoginResponse passwordLogin(CompatPasswordLoginRequest request) {
|
||||
ensureMasterKeyReady();
|
||||
RoleCode roleCode = resolveRoleCode(request.getRole());
|
||||
LoginRequest loginRequest = new LoginRequest();
|
||||
loginRequest.setRoleCode(roleCode.getCode());
|
||||
loginRequest.setPassword(request.getPassword());
|
||||
return authService.login(loginRequest);
|
||||
}
|
||||
|
||||
public LoginResponse ukeyLogin(CompatUkeyLoginRequest request) {
|
||||
ensureMasterKeyReady();
|
||||
RoleCode roleCode = resolveRoleCode(request.getRole());
|
||||
List<RoleUkeyBindingEntity> activeBindings = roleUkeyBindingRepository.findActiveByRoleCode(roleCode.getCode());
|
||||
validateUkeyCount(roleCode, activeBindings, request.getAuthInfo());
|
||||
|
||||
Map<String, RoleUkeyBindingEntity> bindingsByPubKey = activeBindings.stream()
|
||||
.collect(Collectors.toMap(RoleUkeyBindingEntity::getUkeyPubkey, item -> item, (left, right) -> left, LinkedHashMap::new));
|
||||
Set<String> requestPubKeys = request.getAuthInfo().stream()
|
||||
.map(CompatUkeyLoginRequest.LoginAuthInfo::getPubKey)
|
||||
.collect(Collectors.toSet());
|
||||
if (requestPubKeys.size() != request.getAuthInfo().size() || !bindingsByPubKey.keySet().containsAll(requestPubKeys)) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "ukey auth info does not match bound role");
|
||||
}
|
||||
|
||||
ukeyLoginRandomService.assertIssued(
|
||||
roleCode.getCode(),
|
||||
request.getAuthInfo().stream().map(CompatUkeyLoginRequest.LoginAuthInfo::getRb).toList()
|
||||
);
|
||||
|
||||
String authKeyPair = lmkService.exportIkPublicKeyHex();
|
||||
List<String> matchedSerials = new ArrayList<>();
|
||||
for (CompatUkeyLoginRequest.LoginAuthInfo loginAuthInfo : request.getAuthInfo()) {
|
||||
RoleUkeyBindingEntity binding = bindingsByPubKey.get(loginAuthInfo.getPubKey());
|
||||
compatUkeyVerifier.verifyIssuedBinding(buildIssuePayload(request.getRole(), loginAuthInfo, authKeyPair), loginAuthInfo.getIssueSign());
|
||||
compatUkeyVerifier.verifyLoginSignature(loginAuthInfo.getPubKey(), loginAuthInfo.getLoginSignData(), loginAuthInfo.getLoginSign());
|
||||
matchedSerials.add(binding.getUkeySerial());
|
||||
}
|
||||
|
||||
LoginRequest loginRequest = new LoginRequest();
|
||||
loginRequest.setRoleCode(roleCode.getCode());
|
||||
loginRequest.setPassword(request.getPassword());
|
||||
loginRequest.setUkeySerials(matchedSerials);
|
||||
return authService.login(loginRequest);
|
||||
}
|
||||
|
||||
private void ensureMasterKeyReady() {
|
||||
MasterKeyStatus.StatusDetail status = lmkService.getMasterKeyStatus();
|
||||
if (status == null || status.getCode() == MasterKeyStatus.ABNORMAL.getCode()) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "master key is not ready");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateUkeyCount(
|
||||
RoleCode roleCode,
|
||||
List<RoleUkeyBindingEntity> activeBindings,
|
||||
List<CompatUkeyLoginRequest.LoginAuthInfo> authInfos
|
||||
) {
|
||||
if (authInfos == null || authInfos.size() != roleCode.getRequiredUkeyCount()) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "ukey count does not satisfy role requirement");
|
||||
}
|
||||
if (activeBindings.size() != roleCode.getRequiredUkeyCount()) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "ukey count does not satisfy role requirement");
|
||||
}
|
||||
}
|
||||
|
||||
private String buildIssuePayload(String legacyRole, CompatUkeyLoginRequest.LoginAuthInfo loginAuthInfo, String authKeyPair) {
|
||||
UKeySignDTO uKeySignDTO = new UKeySignDTO();
|
||||
uKeySignDTO.setPubKey(loginAuthInfo.getPubKey());
|
||||
uKeySignDTO.setRole(normalizeLegacyRole(legacyRole));
|
||||
uKeySignDTO.setUid(loginAuthInfo.getUid());
|
||||
uKeySignDTO.setRid(loginAuthInfo.getRid());
|
||||
try {
|
||||
return objectMapper.writeValueAsString(UKeySignEntity.getInstance(uKeySignDTO, authKeyPair));
|
||||
} catch (JsonProcessingException ex) {
|
||||
throw new IllegalStateException("serialize ukey issue payload failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private RoleCode resolveRoleCode(String role) {
|
||||
return switch (normalizeLegacyRole(role)) {
|
||||
case "superadmin" -> RoleCode.SUPER_ADMIN;
|
||||
case "keyadmin" -> RoleCode.KEY_ADMIN;
|
||||
case "auditadmin" -> RoleCode.AUDIT_ADMIN;
|
||||
case "configadmin", "opsadmin" -> RoleCode.OPS_ADMIN;
|
||||
case "super_admin" -> RoleCode.SUPER_ADMIN;
|
||||
case "key_admin" -> RoleCode.KEY_ADMIN;
|
||||
case "audit_admin" -> RoleCode.AUDIT_ADMIN;
|
||||
case "ops_admin" -> RoleCode.OPS_ADMIN;
|
||||
default -> throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "invalid role");
|
||||
};
|
||||
}
|
||||
|
||||
private String normalizeLegacyRole(String role) {
|
||||
return role == null ? "" : role.trim().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
public interface CompatUkeyVerifier {
|
||||
|
||||
void verifyIssuedBinding(String payload, String issueSign);
|
||||
|
||||
void verifyLoginSignature(String pubKey, String loginSignData, String loginSign);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
import com.cisd.tms.common.enums.ErrorCode;
|
||||
import com.cisd.tms.common.exception.BizException;
|
||||
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class InMemoryUkeyLoginRandomService implements UkeyLoginRandomService {
|
||||
|
||||
private static final int RANDOM_BYTES = 16;
|
||||
private static final int EXPIRE_MINUTES = 10;
|
||||
|
||||
private final PcieCryptoService pcieCryptoService;
|
||||
private final Clock clock;
|
||||
private final Map<String, IssuedRandoms> store = new ConcurrentHashMap<>();
|
||||
|
||||
@Autowired
|
||||
public InMemoryUkeyLoginRandomService(PcieCryptoService pcieCryptoService) {
|
||||
this(pcieCryptoService, Clock.systemUTC());
|
||||
}
|
||||
|
||||
InMemoryUkeyLoginRandomService(PcieCryptoService pcieCryptoService, Clock clock) {
|
||||
this.pcieCryptoService = pcieCryptoService;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> issue(String roleCode, int count) {
|
||||
if (count <= 0) {
|
||||
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "count must be positive");
|
||||
}
|
||||
List<String> randoms = new ArrayList<>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
randoms.add(Hex.toHexString(pcieCryptoService.generateRandom(RANDOM_BYTES)));
|
||||
}
|
||||
store.put(roleCode, new IssuedRandoms(randoms, clock.instant().plus(EXPIRE_MINUTES, ChronoUnit.MINUTES)));
|
||||
return randoms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertIssued(String roleCode, List<String> randoms) {
|
||||
IssuedRandoms issuedRandoms = store.remove(roleCode);
|
||||
if (issuedRandoms == null || issuedRandoms.expiresAt().isBefore(clock.instant())) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "login randoms are missing or expired");
|
||||
}
|
||||
if (randoms == null || randoms.size() != issuedRandoms.randoms().size() || !issuedRandoms.randoms().containsAll(randoms)) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "login random verification failed");
|
||||
}
|
||||
}
|
||||
|
||||
private record IssuedRandoms(List<String> randoms, Instant expiresAt) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
public interface PasswordHasher {
|
||||
|
||||
String hash(String password, String salt);
|
||||
|
||||
boolean matches(String rawPassword, String salt, String expectedHash);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Pbkdf2PasswordHasher implements PasswordHasher {
|
||||
|
||||
private static final int ITERATIONS = 65_536;
|
||||
private static final int KEY_LENGTH = 256;
|
||||
|
||||
@Override
|
||||
public String hash(String password, String salt) {
|
||||
try {
|
||||
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(StandardCharsets.UTF_8), ITERATIONS, KEY_LENGTH);
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
return Base64.getEncoder().encodeToString(keyFactory.generateSecret(spec).getEncoded());
|
||||
} catch (GeneralSecurityException ex) {
|
||||
throw new IllegalStateException("failed to hash password", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String rawPassword, String salt, String expectedHash) {
|
||||
byte[] actual = hash(rawPassword, salt).getBytes(StandardCharsets.UTF_8);
|
||||
byte[] expected = expectedHash.getBytes(StandardCharsets.UTF_8);
|
||||
return MessageDigest.isEqual(actual, expected);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
import com.cisd.tms.common.enums.ErrorCode;
|
||||
import com.cisd.tms.common.exception.BizException;
|
||||
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
|
||||
import com.cisd.tms.integration.crypto.pcie.model.EccExternalVerifyRequest;
|
||||
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
|
||||
import com.cisd.tms.modules.mk.service.LmkService;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PcieCompatUkeyVerifier implements CompatUkeyVerifier {
|
||||
|
||||
private final LmkService lmkService;
|
||||
private final PcieCryptoService pcieCryptoService;
|
||||
|
||||
public PcieCompatUkeyVerifier(LmkService lmkService, PcieCryptoService pcieCryptoService) {
|
||||
this.lmkService = lmkService;
|
||||
this.pcieCryptoService = pcieCryptoService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyIssuedBinding(String payload, String issueSign) {
|
||||
try {
|
||||
lmkService.verifyIk(payload, issueSign);
|
||||
} catch (BizException ex) {
|
||||
throw ex;
|
||||
} catch (RuntimeException ex) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "issue signature verification failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyLoginSignature(String pubKey, String loginSignData, String loginSign) {
|
||||
EccExternalVerifyRequest request = new EccExternalVerifyRequest();
|
||||
request.setAlgId(Gm0018AlgorithmIds.SM2_SIGN);
|
||||
request.setPublicKeyBlob(decodeBlob(pubKey, "login public key is invalid"));
|
||||
request.setData(loginSignData.getBytes(StandardCharsets.UTF_8));
|
||||
request.setSignature(decodeBlob(loginSign, "login signature is invalid"));
|
||||
try {
|
||||
pcieCryptoService.eccExternalVerify(request);
|
||||
} catch (BizException ex) {
|
||||
throw ex;
|
||||
} catch (RuntimeException ex) {
|
||||
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "login signature verification failed");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] decodeBlob(String value, String message) {
|
||||
String normalized = value == null ? "" : value.trim();
|
||||
if (normalized.isEmpty()) {
|
||||
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), message);
|
||||
}
|
||||
if (normalized.matches("(?i)^[0-9a-f]+$") && normalized.length() % 2 == 0) {
|
||||
return Hex.decode(normalized);
|
||||
}
|
||||
try {
|
||||
return Base64.getDecoder().decode(normalized);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.cisd.tms.modules.auth.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UkeyLoginRandomService {
|
||||
|
||||
List<String> issue(String roleCode, int count);
|
||||
|
||||
void assertIssued(String roleCode, List<String> randoms);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.cisd.tms.modules.device.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "tms.device.profile")
|
||||
public class DeviceProfileProperties {
|
||||
|
||||
private String model = "SYD7108";
|
||||
private String name = "跨境支付终端一体机";
|
||||
private String cpuModelDefault = "";
|
||||
private String memoryTotalDefault = "16GB";
|
||||
private String diskTotalDefault = "256G";
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCpuModelDefault() {
|
||||
return cpuModelDefault;
|
||||
}
|
||||
|
||||
public void setCpuModelDefault(String cpuModelDefault) {
|
||||
this.cpuModelDefault = cpuModelDefault;
|
||||
}
|
||||
|
||||
public String getMemoryTotalDefault() {
|
||||
return memoryTotalDefault;
|
||||
}
|
||||
|
||||
public void setMemoryTotalDefault(String memoryTotalDefault) {
|
||||
this.memoryTotalDefault = memoryTotalDefault;
|
||||
}
|
||||
|
||||
public String getDiskTotalDefault() {
|
||||
return diskTotalDefault;
|
||||
}
|
||||
|
||||
public void setDiskTotalDefault(String diskTotalDefault) {
|
||||
this.diskTotalDefault = diskTotalDefault;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,12 +8,13 @@ import com.cisd.tms.modules.device.dto.DeviceRuntimeStatusResponse;
|
||||
import com.cisd.tms.modules.device.service.DeviceProfileService;
|
||||
import com.cisd.tms.modules.device.service.DeviceRuntimeStatusService;
|
||||
import com.cisd.tms.modules.device.service.DeviceService;
|
||||
import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@@ -62,10 +63,8 @@ public class DeviceController {
|
||||
|
||||
@PostMapping("/restart")
|
||||
@Operation(summary = "重启设备服务", description = "受理设备重启请求,并记录触发操作的内部用户。")
|
||||
public ApiResponse<DeviceActionResponse> restart(
|
||||
@Parameter(description = "触发重启的操作人,来自内部鉴权链路透传的 X-User 请求头")
|
||||
@RequestHeader(value = "X-User", required = false) String operator
|
||||
) {
|
||||
public ApiResponse<DeviceActionResponse> restart(HttpServletRequest request) {
|
||||
String operator = (String) request.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE);
|
||||
return ApiResponse.success(deviceService.restart(operator));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "加密卡运行状态")
|
||||
public class CryptoCardRuntimeStatus {
|
||||
|
||||
@Schema(description = "状态", example = "NORMAL")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "状态说明", example = "就绪状态")
|
||||
private String message;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "设备基础信息")
|
||||
public class DeviceProfileDeviceSection {
|
||||
|
||||
@Schema(description = "设备型号", example = "SYD7108")
|
||||
private String model;
|
||||
@Schema(description = "设备名称", example = "跨境支付终端一体机")
|
||||
private String name;
|
||||
@Schema(description = "设备序列号", example = "1234567890ABCDEF")
|
||||
private String serialNumber;
|
||||
@Schema(description = "设备版本", example = "V1.00")
|
||||
private String deviceVersion;
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSerialNumber() {
|
||||
return serialNumber;
|
||||
}
|
||||
|
||||
public void setSerialNumber(String serialNumber) {
|
||||
this.serialNumber = serialNumber;
|
||||
}
|
||||
|
||||
public String getDeviceVersion() {
|
||||
return deviceVersion;
|
||||
}
|
||||
|
||||
public void setDeviceVersion(String deviceVersion) {
|
||||
this.deviceVersion = deviceVersion;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "设备硬件信息")
|
||||
public class DeviceProfileHardwareSection {
|
||||
|
||||
@Schema(description = "密码卡名称", example = "SYD1408加密卡")
|
||||
private String cryptoCardName;
|
||||
@Schema(description = "CPU 型号", example = "Hygon C86-3G (OPN:3350)")
|
||||
private String cpuModel;
|
||||
@Schema(description = "内存总量", example = "32GB")
|
||||
private String memoryTotal;
|
||||
@Schema(description = "磁盘总量", example = "953.87GB")
|
||||
private String diskTotal;
|
||||
|
||||
public String getCryptoCardName() {
|
||||
return cryptoCardName;
|
||||
}
|
||||
|
||||
public void setCryptoCardName(String cryptoCardName) {
|
||||
this.cryptoCardName = cryptoCardName;
|
||||
}
|
||||
|
||||
public String getCpuModel() {
|
||||
return cpuModel;
|
||||
}
|
||||
|
||||
public void setCpuModel(String cpuModel) {
|
||||
this.cpuModel = cpuModel;
|
||||
}
|
||||
|
||||
public String getMemoryTotal() {
|
||||
return memoryTotal;
|
||||
}
|
||||
|
||||
public void setMemoryTotal(String memoryTotal) {
|
||||
this.memoryTotal = memoryTotal;
|
||||
}
|
||||
|
||||
public String getDiskTotal() {
|
||||
return diskTotal;
|
||||
}
|
||||
|
||||
public void setDiskTotal(String diskTotal) {
|
||||
this.diskTotal = diskTotal;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "设备画像响应")
|
||||
public class DeviceProfileResponse {
|
||||
|
||||
@Schema(description = "设备基础信息")
|
||||
private DeviceProfileDeviceSection device;
|
||||
@Schema(description = "设备硬件信息")
|
||||
private DeviceProfileHardwareSection hardware;
|
||||
@Schema(description = "软件版本信息")
|
||||
private List<DeviceProfileSoftwareItem> software = new ArrayList<>();
|
||||
|
||||
public DeviceProfileDeviceSection getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setDevice(DeviceProfileDeviceSection device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public DeviceProfileHardwareSection getHardware() {
|
||||
return hardware;
|
||||
}
|
||||
|
||||
public void setHardware(DeviceProfileHardwareSection hardware) {
|
||||
this.hardware = hardware;
|
||||
}
|
||||
|
||||
public List<DeviceProfileSoftwareItem> getSoftware() {
|
||||
return software;
|
||||
}
|
||||
|
||||
public void setSoftware(List<DeviceProfileSoftwareItem> software) {
|
||||
this.software = software;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "软件组件信息")
|
||||
public class DeviceProfileSoftwareItem {
|
||||
|
||||
@Schema(description = "组件编码", example = "RABBITMQ")
|
||||
private String componentCode;
|
||||
@Schema(description = "组件名称", example = "RabbitMQ")
|
||||
private String componentName;
|
||||
@Schema(description = "组件版本", example = "RabbitMQ V3.8.21")
|
||||
private String version;
|
||||
|
||||
public String getComponentCode() {
|
||||
return componentCode;
|
||||
}
|
||||
|
||||
public void setComponentCode(String componentCode) {
|
||||
this.componentCode = componentCode;
|
||||
}
|
||||
|
||||
public String getComponentName() {
|
||||
return componentName;
|
||||
}
|
||||
|
||||
public void setComponentName(String componentName) {
|
||||
this.componentName = componentName;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "设备运行状态响应")
|
||||
public class DeviceRuntimeStatusResponse {
|
||||
|
||||
@Schema(description = "硬件运行状态")
|
||||
private HardwareRuntimeStatusSection hardware;
|
||||
|
||||
@Schema(description = "软件运行状态")
|
||||
private List<SoftwareRuntimeStatusItem> software = new ArrayList<>();
|
||||
|
||||
@Schema(description = "采集时间", example = "2026-03-13T14:30:00+08:00")
|
||||
private String collectedAt;
|
||||
|
||||
public HardwareRuntimeStatusSection getHardware() {
|
||||
return hardware;
|
||||
}
|
||||
|
||||
public void setHardware(HardwareRuntimeStatusSection hardware) {
|
||||
this.hardware = hardware;
|
||||
}
|
||||
|
||||
public List<SoftwareRuntimeStatusItem> getSoftware() {
|
||||
return software;
|
||||
}
|
||||
|
||||
public void setSoftware(List<SoftwareRuntimeStatusItem> software) {
|
||||
this.software = software;
|
||||
}
|
||||
|
||||
public String getCollectedAt() {
|
||||
return collectedAt;
|
||||
}
|
||||
|
||||
public void setCollectedAt(String collectedAt) {
|
||||
this.collectedAt = collectedAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "硬件运行状态")
|
||||
public class HardwareRuntimeStatusSection {
|
||||
|
||||
@Schema(description = "CPU 运行状态")
|
||||
private UsageMetricStatus cpu;
|
||||
|
||||
@Schema(description = "内存运行状态")
|
||||
private UsageMetricStatus memory;
|
||||
|
||||
@Schema(description = "磁盘运行状态")
|
||||
private UsageMetricStatus disk;
|
||||
|
||||
@Schema(description = "加密卡运行状态")
|
||||
private CryptoCardRuntimeStatus cryptoCard;
|
||||
|
||||
public UsageMetricStatus getCpu() {
|
||||
return cpu;
|
||||
}
|
||||
|
||||
public void setCpu(UsageMetricStatus cpu) {
|
||||
this.cpu = cpu;
|
||||
}
|
||||
|
||||
public UsageMetricStatus getMemory() {
|
||||
return memory;
|
||||
}
|
||||
|
||||
public void setMemory(UsageMetricStatus memory) {
|
||||
this.memory = memory;
|
||||
}
|
||||
|
||||
public UsageMetricStatus getDisk() {
|
||||
return disk;
|
||||
}
|
||||
|
||||
public void setDisk(UsageMetricStatus disk) {
|
||||
this.disk = disk;
|
||||
}
|
||||
|
||||
public CryptoCardRuntimeStatus getCryptoCard() {
|
||||
return cryptoCard;
|
||||
}
|
||||
|
||||
public void setCryptoCard(CryptoCardRuntimeStatus cryptoCard) {
|
||||
this.cryptoCard = cryptoCard;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "软件运行状态项")
|
||||
public class SoftwareRuntimeStatusItem {
|
||||
|
||||
@Schema(description = "组件编码", example = "RABBITMQ")
|
||||
private String componentCode;
|
||||
|
||||
@Schema(description = "组件名称", example = "消息队列")
|
||||
private String componentName;
|
||||
|
||||
@Schema(description = "展示名称", example = "RabbitMQ V3.8.21")
|
||||
private String displayName;
|
||||
|
||||
@Schema(description = "状态", example = "NORMAL")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "状态说明", example = "正常")
|
||||
private String message;
|
||||
|
||||
public String getComponentCode() {
|
||||
return componentCode;
|
||||
}
|
||||
|
||||
public void setComponentCode(String componentCode) {
|
||||
this.componentCode = componentCode;
|
||||
}
|
||||
|
||||
public String getComponentName() {
|
||||
return componentName;
|
||||
}
|
||||
|
||||
public void setComponentName(String componentName) {
|
||||
this.componentName = componentName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.cisd.tms.modules.device.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "资源使用量状态")
|
||||
public class UsageMetricStatus {
|
||||
|
||||
@Schema(description = "已使用容量(GB)", example = "23.55")
|
||||
private Double usedGb;
|
||||
|
||||
@Schema(description = "总容量(GB)", example = "32.0")
|
||||
private Double totalGb;
|
||||
|
||||
@Schema(description = "使用率百分比", example = "73.59")
|
||||
private Double usagePercent;
|
||||
|
||||
@Schema(description = "状态", example = "NORMAL")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "状态说明", example = "正常")
|
||||
private String message;
|
||||
|
||||
public Double getUsedGb() {
|
||||
return usedGb;
|
||||
}
|
||||
|
||||
public void setUsedGb(Double usedGb) {
|
||||
this.usedGb = usedGb;
|
||||
}
|
||||
|
||||
public Double getTotalGb() {
|
||||
return totalGb;
|
||||
}
|
||||
|
||||
public void setTotalGb(Double totalGb) {
|
||||
this.totalGb = totalGb;
|
||||
}
|
||||
|
||||
public Double getUsagePercent() {
|
||||
return usagePercent;
|
||||
}
|
||||
|
||||
public void setUsagePercent(Double usagePercent) {
|
||||
this.usagePercent = usagePercent;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
||||
public class CryptoBackupUserKeyInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(0)
|
||||
private int keyType;
|
||||
|
||||
@Min(1)
|
||||
private int outBufferSize;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public void setKeyType(int keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public int getOutBufferSize() {
|
||||
return outBufferSize;
|
||||
}
|
||||
|
||||
public void setOutBufferSize(int outBufferSize) {
|
||||
this.outBufferSize = outBufferSize;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoChangePrivateKeyPasswordInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@NotBlank
|
||||
private String oldPasswordBase64;
|
||||
|
||||
@NotBlank
|
||||
private String newPasswordBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public String getOldPasswordBase64() {
|
||||
return oldPasswordBase64;
|
||||
}
|
||||
|
||||
public void setOldPasswordBase64(String oldPasswordBase64) {
|
||||
this.oldPasswordBase64 = oldPasswordBase64;
|
||||
}
|
||||
|
||||
public String getNewPasswordBase64() {
|
||||
return newPasswordBase64;
|
||||
}
|
||||
|
||||
public void setNewPasswordBase64(String newPasswordBase64) {
|
||||
this.newPasswordBase64 = newPasswordBase64;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoDigestInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int algId;
|
||||
|
||||
@NotBlank
|
||||
private String dataBase64;
|
||||
|
||||
@Min(1)
|
||||
private int outBufferSize = 64;
|
||||
|
||||
public int getAlgId() {
|
||||
return algId;
|
||||
}
|
||||
|
||||
public void setAlgId(int algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
public String getDataBase64() {
|
||||
return dataBase64;
|
||||
}
|
||||
|
||||
public void setDataBase64(String dataBase64) {
|
||||
this.dataBase64 = dataBase64;
|
||||
}
|
||||
|
||||
public int getOutBufferSize() {
|
||||
return outBufferSize;
|
||||
}
|
||||
|
||||
public void setOutBufferSize(int outBufferSize) {
|
||||
this.outBufferSize = outBufferSize;
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoExchangeEnvelopeEccInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(1)
|
||||
private int algId;
|
||||
|
||||
@NotBlank
|
||||
private String publicKeyBase64;
|
||||
|
||||
@NotBlank
|
||||
private String inputEnvelopeBase64;
|
||||
|
||||
@Min(1)
|
||||
private int outBufferSize;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getAlgId() {
|
||||
return algId;
|
||||
}
|
||||
|
||||
public void setAlgId(int algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
public String getPublicKeyBase64() {
|
||||
return publicKeyBase64;
|
||||
}
|
||||
|
||||
public void setPublicKeyBase64(String publicKeyBase64) {
|
||||
this.publicKeyBase64 = publicKeyBase64;
|
||||
}
|
||||
|
||||
public String getInputEnvelopeBase64() {
|
||||
return inputEnvelopeBase64;
|
||||
}
|
||||
|
||||
public void setInputEnvelopeBase64(String inputEnvelopeBase64) {
|
||||
this.inputEnvelopeBase64 = inputEnvelopeBase64;
|
||||
}
|
||||
|
||||
public int getOutBufferSize() {
|
||||
return outBufferSize;
|
||||
}
|
||||
|
||||
public void setOutBufferSize(int outBufferSize) {
|
||||
this.outBufferSize = outBufferSize;
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoExchangeEnvelopeRsaInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@NotBlank
|
||||
private String publicKeyBase64;
|
||||
|
||||
@NotBlank
|
||||
private String inputEnvelopeBase64;
|
||||
|
||||
@Min(1)
|
||||
private int outBufferSize;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public String getPublicKeyBase64() {
|
||||
return publicKeyBase64;
|
||||
}
|
||||
|
||||
public void setPublicKeyBase64(String publicKeyBase64) {
|
||||
this.publicKeyBase64 = publicKeyBase64;
|
||||
}
|
||||
|
||||
public String getInputEnvelopeBase64() {
|
||||
return inputEnvelopeBase64;
|
||||
}
|
||||
|
||||
public void setInputEnvelopeBase64(String inputEnvelopeBase64) {
|
||||
this.inputEnvelopeBase64 = inputEnvelopeBase64;
|
||||
}
|
||||
|
||||
public int getOutBufferSize() {
|
||||
return outBufferSize;
|
||||
}
|
||||
|
||||
public void setOutBufferSize(int outBufferSize) {
|
||||
this.outBufferSize = outBufferSize;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoFileCreateInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String fileName;
|
||||
|
||||
@Min(1)
|
||||
private int fileSize;
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public int getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
public void setFileSize(int fileSize) {
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoFileDeleteInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String fileName;
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoFileReadInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String fileName;
|
||||
|
||||
@Min(0)
|
||||
private int offset;
|
||||
|
||||
@Min(1)
|
||||
private int readLength;
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getReadLength() {
|
||||
return readLength;
|
||||
}
|
||||
|
||||
public void setReadLength(int readLength) {
|
||||
this.readLength = readLength;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoFileWriteInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String fileName;
|
||||
|
||||
@Min(0)
|
||||
private int offset;
|
||||
|
||||
@NotBlank
|
||||
private String dataBase64;
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public String getDataBase64() {
|
||||
return dataBase64;
|
||||
}
|
||||
|
||||
public void setDataBase64(String dataBase64) {
|
||||
this.dataBase64 = dataBase64;
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoGenerateAgreementDataAndKeyEccInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int iskIndex;
|
||||
|
||||
@Min(1)
|
||||
private int keyBits;
|
||||
|
||||
@NotBlank
|
||||
private String responseIdBase64;
|
||||
|
||||
@NotBlank
|
||||
private String sponsorIdBase64;
|
||||
|
||||
@NotBlank
|
||||
private String sponsorPublicKeyBase64;
|
||||
|
||||
@NotBlank
|
||||
private String sponsorTmpPublicKeyBase64;
|
||||
|
||||
@Min(1)
|
||||
private int responsePublicKeyBufferSize;
|
||||
|
||||
@Min(1)
|
||||
private int responseTmpPublicKeyBufferSize;
|
||||
|
||||
public int getIskIndex() {
|
||||
return iskIndex;
|
||||
}
|
||||
|
||||
public void setIskIndex(int iskIndex) {
|
||||
this.iskIndex = iskIndex;
|
||||
}
|
||||
|
||||
public int getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public void setKeyBits(int keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public String getResponseIdBase64() {
|
||||
return responseIdBase64;
|
||||
}
|
||||
|
||||
public void setResponseIdBase64(String responseIdBase64) {
|
||||
this.responseIdBase64 = responseIdBase64;
|
||||
}
|
||||
|
||||
public String getSponsorIdBase64() {
|
||||
return sponsorIdBase64;
|
||||
}
|
||||
|
||||
public void setSponsorIdBase64(String sponsorIdBase64) {
|
||||
this.sponsorIdBase64 = sponsorIdBase64;
|
||||
}
|
||||
|
||||
public String getSponsorPublicKeyBase64() {
|
||||
return sponsorPublicKeyBase64;
|
||||
}
|
||||
|
||||
public void setSponsorPublicKeyBase64(String sponsorPublicKeyBase64) {
|
||||
this.sponsorPublicKeyBase64 = sponsorPublicKeyBase64;
|
||||
}
|
||||
|
||||
public String getSponsorTmpPublicKeyBase64() {
|
||||
return sponsorTmpPublicKeyBase64;
|
||||
}
|
||||
|
||||
public void setSponsorTmpPublicKeyBase64(String sponsorTmpPublicKeyBase64) {
|
||||
this.sponsorTmpPublicKeyBase64 = sponsorTmpPublicKeyBase64;
|
||||
}
|
||||
|
||||
public int getResponsePublicKeyBufferSize() {
|
||||
return responsePublicKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setResponsePublicKeyBufferSize(int responsePublicKeyBufferSize) {
|
||||
this.responsePublicKeyBufferSize = responsePublicKeyBufferSize;
|
||||
}
|
||||
|
||||
public int getResponseTmpPublicKeyBufferSize() {
|
||||
return responseTmpPublicKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setResponseTmpPublicKeyBufferSize(int responseTmpPublicKeyBufferSize) {
|
||||
this.responseTmpPublicKeyBufferSize = responseTmpPublicKeyBufferSize;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
||||
public class CryptoGenerateKekInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int keyBits;
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
public int getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public void setKeyBits(int keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
||||
public class CryptoGenerateKeyPairInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int keyBits;
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(0)
|
||||
private int keyType;
|
||||
|
||||
public int getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public void setKeyBits(int keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public void setKeyType(int keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoGenerateSessionKeyEccInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int iskIndex;
|
||||
|
||||
@Min(1)
|
||||
private int keyBits;
|
||||
|
||||
@NotBlank
|
||||
private String sponsorIdBase64;
|
||||
|
||||
@NotBlank
|
||||
private String responseIdBase64;
|
||||
|
||||
@NotBlank
|
||||
private String responsePublicKeyBase64;
|
||||
|
||||
@NotBlank
|
||||
private String responseTmpPublicKeyBase64;
|
||||
|
||||
@Min(1)
|
||||
private int sponsorPublicKeyBufferSize;
|
||||
|
||||
@Min(1)
|
||||
private int sponsorTmpPublicKeyBufferSize;
|
||||
|
||||
@Min(1)
|
||||
private int sessionKeyBufferSize;
|
||||
|
||||
public int getIskIndex() {
|
||||
return iskIndex;
|
||||
}
|
||||
|
||||
public void setIskIndex(int iskIndex) {
|
||||
this.iskIndex = iskIndex;
|
||||
}
|
||||
|
||||
public int getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public void setKeyBits(int keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public String getSponsorIdBase64() {
|
||||
return sponsorIdBase64;
|
||||
}
|
||||
|
||||
public void setSponsorIdBase64(String sponsorIdBase64) {
|
||||
this.sponsorIdBase64 = sponsorIdBase64;
|
||||
}
|
||||
|
||||
public String getResponseIdBase64() {
|
||||
return responseIdBase64;
|
||||
}
|
||||
|
||||
public void setResponseIdBase64(String responseIdBase64) {
|
||||
this.responseIdBase64 = responseIdBase64;
|
||||
}
|
||||
|
||||
public String getResponsePublicKeyBase64() {
|
||||
return responsePublicKeyBase64;
|
||||
}
|
||||
|
||||
public void setResponsePublicKeyBase64(String responsePublicKeyBase64) {
|
||||
this.responsePublicKeyBase64 = responsePublicKeyBase64;
|
||||
}
|
||||
|
||||
public String getResponseTmpPublicKeyBase64() {
|
||||
return responseTmpPublicKeyBase64;
|
||||
}
|
||||
|
||||
public void setResponseTmpPublicKeyBase64(String responseTmpPublicKeyBase64) {
|
||||
this.responseTmpPublicKeyBase64 = responseTmpPublicKeyBase64;
|
||||
}
|
||||
|
||||
public int getSponsorPublicKeyBufferSize() {
|
||||
return sponsorPublicKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setSponsorPublicKeyBufferSize(int sponsorPublicKeyBufferSize) {
|
||||
this.sponsorPublicKeyBufferSize = sponsorPublicKeyBufferSize;
|
||||
}
|
||||
|
||||
public int getSponsorTmpPublicKeyBufferSize() {
|
||||
return sponsorTmpPublicKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setSponsorTmpPublicKeyBufferSize(int sponsorTmpPublicKeyBufferSize) {
|
||||
this.sponsorTmpPublicKeyBufferSize = sponsorTmpPublicKeyBufferSize;
|
||||
}
|
||||
|
||||
public int getSessionKeyBufferSize() {
|
||||
return sessionKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setSessionKeyBufferSize(int sessionKeyBufferSize) {
|
||||
this.sessionKeyBufferSize = sessionKeyBufferSize;
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
||||
public class CryptoGenerateStandardEccKeyPairInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int algId;
|
||||
|
||||
@Min(1)
|
||||
private int keyBits;
|
||||
|
||||
@Min(1)
|
||||
private int publicKeyBufferSize;
|
||||
|
||||
@Min(1)
|
||||
private int privateKeyBufferSize;
|
||||
|
||||
public int getAlgId() {
|
||||
return algId;
|
||||
}
|
||||
|
||||
public void setAlgId(int algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
public int getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public void setKeyBits(int keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public int getPublicKeyBufferSize() {
|
||||
return publicKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setPublicKeyBufferSize(int publicKeyBufferSize) {
|
||||
this.publicKeyBufferSize = publicKeyBufferSize;
|
||||
}
|
||||
|
||||
public int getPrivateKeyBufferSize() {
|
||||
return privateKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setPrivateKeyBufferSize(int privateKeyBufferSize) {
|
||||
this.privateKeyBufferSize = privateKeyBufferSize;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
||||
public class CryptoGenerateStandardRsaKeyPairInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int keyBits;
|
||||
|
||||
@Min(1)
|
||||
private int publicKeyBufferSize;
|
||||
|
||||
@Min(1)
|
||||
private int privateKeyBufferSize;
|
||||
|
||||
public int getKeyBits() {
|
||||
return keyBits;
|
||||
}
|
||||
|
||||
public void setKeyBits(int keyBits) {
|
||||
this.keyBits = keyBits;
|
||||
}
|
||||
|
||||
public int getPublicKeyBufferSize() {
|
||||
return publicKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setPublicKeyBufferSize(int publicKeyBufferSize) {
|
||||
this.publicKeyBufferSize = publicKeyBufferSize;
|
||||
}
|
||||
|
||||
public int getPrivateKeyBufferSize() {
|
||||
return privateKeyBufferSize;
|
||||
}
|
||||
|
||||
public void setPrivateKeyBufferSize(int privateKeyBufferSize) {
|
||||
this.privateKeyBufferSize = privateKeyBufferSize;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoHmacInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int algId;
|
||||
|
||||
@NotBlank
|
||||
private String keyBase64;
|
||||
|
||||
@NotBlank
|
||||
private String dataBase64;
|
||||
|
||||
public int getAlgId() {
|
||||
return algId;
|
||||
}
|
||||
|
||||
public void setAlgId(int algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
public String getKeyBase64() {
|
||||
return keyBase64;
|
||||
}
|
||||
|
||||
public void setKeyBase64(String keyBase64) {
|
||||
this.keyBase64 = keyBase64;
|
||||
}
|
||||
|
||||
public String getDataBase64() {
|
||||
return dataBase64;
|
||||
}
|
||||
|
||||
public void setDataBase64(String dataBase64) {
|
||||
this.dataBase64 = dataBase64;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoImportEncryptedKeyPairEccInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@NotBlank
|
||||
private String envelopedKeyBlobBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public String getEnvelopedKeyBlobBase64() {
|
||||
return envelopedKeyBlobBase64;
|
||||
}
|
||||
|
||||
public void setEnvelopedKeyBlobBase64(String envelopedKeyBlobBase64) {
|
||||
this.envelopedKeyBlobBase64 = envelopedKeyBlobBase64;
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoImportEncryptedKeyPairRsaInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(1)
|
||||
private int symAlgId;
|
||||
|
||||
@NotBlank
|
||||
private String wrappedKeyBase64;
|
||||
|
||||
@NotBlank
|
||||
private String encryptedDataBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getSymAlgId() {
|
||||
return symAlgId;
|
||||
}
|
||||
|
||||
public void setSymAlgId(int symAlgId) {
|
||||
this.symAlgId = symAlgId;
|
||||
}
|
||||
|
||||
public String getWrappedKeyBase64() {
|
||||
return wrappedKeyBase64;
|
||||
}
|
||||
|
||||
public void setWrappedKeyBase64(String wrappedKeyBase64) {
|
||||
this.wrappedKeyBase64 = wrappedKeyBase64;
|
||||
}
|
||||
|
||||
public String getEncryptedDataBase64() {
|
||||
return encryptedDataBase64;
|
||||
}
|
||||
|
||||
public void setEncryptedDataBase64(String encryptedDataBase64) {
|
||||
this.encryptedDataBase64 = encryptedDataBase64;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoImportKekInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@NotBlank
|
||||
private String keyDataBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public String getKeyDataBase64() {
|
||||
return keyDataBase64;
|
||||
}
|
||||
|
||||
public void setKeyDataBase64(String keyDataBase64) {
|
||||
this.keyDataBase64 = keyDataBase64;
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoImportKeyPairInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(0)
|
||||
private int keyType;
|
||||
|
||||
@NotBlank
|
||||
private String publicKeyBase64;
|
||||
|
||||
@NotBlank
|
||||
private String privateKeyBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public void setKeyType(int keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public String getPublicKeyBase64() {
|
||||
return publicKeyBase64;
|
||||
}
|
||||
|
||||
public void setPublicKeyBase64(String publicKeyBase64) {
|
||||
this.publicKeyBase64 = publicKeyBase64;
|
||||
}
|
||||
|
||||
public String getPrivateKeyBase64() {
|
||||
return privateKeyBase64;
|
||||
}
|
||||
|
||||
public void setPrivateKeyBase64(String privateKeyBase64) {
|
||||
this.privateKeyBase64 = privateKeyBase64;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoInitIdentifyInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String oldPinBase64;
|
||||
|
||||
@NotBlank
|
||||
private String newPinBase64;
|
||||
|
||||
public String getOldPinBase64() {
|
||||
return oldPinBase64;
|
||||
}
|
||||
|
||||
public void setOldPinBase64(String oldPinBase64) {
|
||||
this.oldPinBase64 = oldPinBase64;
|
||||
}
|
||||
|
||||
public String getNewPinBase64() {
|
||||
return newPinBase64;
|
||||
}
|
||||
|
||||
public void setNewPinBase64(String newPinBase64) {
|
||||
this.newPinBase64 = newPinBase64;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
|
||||
public class CryptoKekComponentExportInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(0)
|
||||
private int componentNum;
|
||||
|
||||
@Min(1)
|
||||
private int componentSize;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getComponentNum() {
|
||||
return componentNum;
|
||||
}
|
||||
|
||||
public void setComponentNum(int componentNum) {
|
||||
this.componentNum = componentNum;
|
||||
}
|
||||
|
||||
public int getComponentSize() {
|
||||
return componentSize;
|
||||
}
|
||||
|
||||
public void setComponentSize(int componentSize) {
|
||||
this.componentSize = componentSize;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoKekComponentImportInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(0)
|
||||
private int componentNum;
|
||||
|
||||
@NotBlank
|
||||
private String componentDataBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getComponentNum() {
|
||||
return componentNum;
|
||||
}
|
||||
|
||||
public void setComponentNum(int componentNum) {
|
||||
this.componentNum = componentNum;
|
||||
}
|
||||
|
||||
public String getComponentDataBase64() {
|
||||
return componentDataBase64;
|
||||
}
|
||||
|
||||
public void setComponentDataBase64(String componentDataBase64) {
|
||||
this.componentDataBase64 = componentDataBase64;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoMacInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int algId;
|
||||
|
||||
@NotBlank
|
||||
private String keyBase64;
|
||||
|
||||
private String ivBase64;
|
||||
|
||||
@NotBlank
|
||||
private String dataBase64;
|
||||
|
||||
@Min(1)
|
||||
private int outBufferSize = 32;
|
||||
|
||||
public int getAlgId() {
|
||||
return algId;
|
||||
}
|
||||
|
||||
public void setAlgId(int algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
public String getKeyBase64() {
|
||||
return keyBase64;
|
||||
}
|
||||
|
||||
public void setKeyBase64(String keyBase64) {
|
||||
this.keyBase64 = keyBase64;
|
||||
}
|
||||
|
||||
public String getIvBase64() {
|
||||
return ivBase64;
|
||||
}
|
||||
|
||||
public void setIvBase64(String ivBase64) {
|
||||
this.ivBase64 = ivBase64;
|
||||
}
|
||||
|
||||
public String getDataBase64() {
|
||||
return dataBase64;
|
||||
}
|
||||
|
||||
public void setDataBase64(String dataBase64) {
|
||||
this.dataBase64 = dataBase64;
|
||||
}
|
||||
|
||||
public int getOutBufferSize() {
|
||||
return outBufferSize;
|
||||
}
|
||||
|
||||
public void setOutBufferSize(int outBufferSize) {
|
||||
this.outBufferSize = outBufferSize;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoPrivateKeyAccessInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@NotBlank
|
||||
private String passwordBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public String getPasswordBase64() {
|
||||
return passwordBase64;
|
||||
}
|
||||
|
||||
public void setPasswordBase64(String passwordBase64) {
|
||||
this.passwordBase64 = passwordBase64;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoReadUkeyIkComponentInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyType;
|
||||
|
||||
@NotBlank
|
||||
private String ukeyPinBase64;
|
||||
|
||||
public int getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public void setKeyType(int keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public String getUkeyPinBase64() {
|
||||
return ukeyPinBase64;
|
||||
}
|
||||
|
||||
public void setUkeyPinBase64(String ukeyPinBase64) {
|
||||
this.ukeyPinBase64 = ukeyPinBase64;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoRecoverKekInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@NotBlank
|
||||
private String encryptedKeyBase64;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public String getEncryptedKeyBase64() {
|
||||
return encryptedKeyBase64;
|
||||
}
|
||||
|
||||
public void setEncryptedKeyBase64(String encryptedKeyBase64) {
|
||||
this.encryptedKeyBase64 = encryptedKeyBase64;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CryptoRecoverLmkExInternalRequest {
|
||||
|
||||
private String componentBase64;
|
||||
private String lmkMacHex;
|
||||
private Map<String, String> components;
|
||||
|
||||
public String getComponentBase64() {
|
||||
return componentBase64;
|
||||
}
|
||||
|
||||
public void setComponentBase64(String componentBase64) {
|
||||
this.componentBase64 = componentBase64;
|
||||
}
|
||||
|
||||
public String getLmkMacHex() {
|
||||
return lmkMacHex;
|
||||
}
|
||||
|
||||
public void setLmkMacHex(String lmkMacHex) {
|
||||
this.lmkMacHex = lmkMacHex;
|
||||
}
|
||||
|
||||
public Map<String, String> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
public void setComponents(Map<String, String> components) {
|
||||
this.components = components;
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoRecoverUserKeyInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int keyIndex;
|
||||
|
||||
@Min(0)
|
||||
private int keyType;
|
||||
|
||||
@NotBlank
|
||||
private String encryptedKeyBase64;
|
||||
|
||||
@Min(0)
|
||||
private int storeFlag = 1;
|
||||
|
||||
public int getKeyIndex() {
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
public void setKeyIndex(int keyIndex) {
|
||||
this.keyIndex = keyIndex;
|
||||
}
|
||||
|
||||
public int getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public void setKeyType(int keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public String getEncryptedKeyBase64() {
|
||||
return encryptedKeyBase64;
|
||||
}
|
||||
|
||||
public void setEncryptedKeyBase64(String encryptedKeyBase64) {
|
||||
this.encryptedKeyBase64 = encryptedKeyBase64;
|
||||
}
|
||||
|
||||
public int getStoreFlag() {
|
||||
return storeFlag;
|
||||
}
|
||||
|
||||
public void setStoreFlag(int storeFlag) {
|
||||
this.storeFlag = storeFlag;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoRestoreAllKeysInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String keyImageBase64;
|
||||
|
||||
public String getKeyImageBase64() {
|
||||
return keyImageBase64;
|
||||
}
|
||||
|
||||
public void setKeyImageBase64(String keyImageBase64) {
|
||||
this.keyImageBase64 = keyImageBase64;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoSymmetricInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int algId;
|
||||
|
||||
@NotBlank
|
||||
private String keyBase64;
|
||||
|
||||
private String ivBase64;
|
||||
|
||||
@NotBlank
|
||||
private String dataBase64;
|
||||
|
||||
@Min(1)
|
||||
private int outBufferSize;
|
||||
|
||||
public int getAlgId() {
|
||||
return algId;
|
||||
}
|
||||
|
||||
public void setAlgId(int algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
public String getKeyBase64() {
|
||||
return keyBase64;
|
||||
}
|
||||
|
||||
public void setKeyBase64(String keyBase64) {
|
||||
this.keyBase64 = keyBase64;
|
||||
}
|
||||
|
||||
public String getIvBase64() {
|
||||
return ivBase64;
|
||||
}
|
||||
|
||||
public void setIvBase64(String ivBase64) {
|
||||
this.ivBase64 = ivBase64;
|
||||
}
|
||||
|
||||
public String getDataBase64() {
|
||||
return dataBase64;
|
||||
}
|
||||
|
||||
public void setDataBase64(String dataBase64) {
|
||||
this.dataBase64 = dataBase64;
|
||||
}
|
||||
|
||||
public int getOutBufferSize() {
|
||||
return outBufferSize;
|
||||
}
|
||||
|
||||
public void setOutBufferSize(int outBufferSize) {
|
||||
this.outBufferSize = outBufferSize;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoSymmetricKekInternalRequest {
|
||||
|
||||
@Min(1)
|
||||
private int algId;
|
||||
|
||||
@Min(0)
|
||||
private int kekIndex;
|
||||
|
||||
@NotBlank
|
||||
private String wrappedKeyBase64;
|
||||
|
||||
private String ivBase64;
|
||||
|
||||
@NotBlank
|
||||
private String dataBase64;
|
||||
|
||||
@Min(1)
|
||||
private int outBufferSize;
|
||||
|
||||
public int getAlgId() {
|
||||
return algId;
|
||||
}
|
||||
|
||||
public void setAlgId(int algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
public int getKekIndex() {
|
||||
return kekIndex;
|
||||
}
|
||||
|
||||
public void setKekIndex(int kekIndex) {
|
||||
this.kekIndex = kekIndex;
|
||||
}
|
||||
|
||||
public String getWrappedKeyBase64() {
|
||||
return wrappedKeyBase64;
|
||||
}
|
||||
|
||||
public void setWrappedKeyBase64(String wrappedKeyBase64) {
|
||||
this.wrappedKeyBase64 = wrappedKeyBase64;
|
||||
}
|
||||
|
||||
public String getIvBase64() {
|
||||
return ivBase64;
|
||||
}
|
||||
|
||||
public void setIvBase64(String ivBase64) {
|
||||
this.ivBase64 = ivBase64;
|
||||
}
|
||||
|
||||
public String getDataBase64() {
|
||||
return dataBase64;
|
||||
}
|
||||
|
||||
public void setDataBase64(String dataBase64) {
|
||||
this.dataBase64 = dataBase64;
|
||||
}
|
||||
|
||||
public int getOutBufferSize() {
|
||||
return outBufferSize;
|
||||
}
|
||||
|
||||
public void setOutBufferSize(int outBufferSize) {
|
||||
this.outBufferSize = outBufferSize;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoUkeyGenerateInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int adminIndex;
|
||||
|
||||
@NotBlank
|
||||
private String ukeyPinBase64;
|
||||
|
||||
@NotBlank
|
||||
private String loginPinBase64;
|
||||
|
||||
public int getAdminIndex() {
|
||||
return adminIndex;
|
||||
}
|
||||
|
||||
public void setAdminIndex(int adminIndex) {
|
||||
this.adminIndex = adminIndex;
|
||||
}
|
||||
|
||||
public String getUkeyPinBase64() {
|
||||
return ukeyPinBase64;
|
||||
}
|
||||
|
||||
public void setUkeyPinBase64(String ukeyPinBase64) {
|
||||
this.ukeyPinBase64 = ukeyPinBase64;
|
||||
}
|
||||
|
||||
public String getLoginPinBase64() {
|
||||
return loginPinBase64;
|
||||
}
|
||||
|
||||
public void setLoginPinBase64(String loginPinBase64) {
|
||||
this.loginPinBase64 = loginPinBase64;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoUkeyLoginInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String ukeyPinBase64;
|
||||
|
||||
@NotBlank
|
||||
private String loginPinBase64;
|
||||
|
||||
public String getUkeyPinBase64() {
|
||||
return ukeyPinBase64;
|
||||
}
|
||||
|
||||
public void setUkeyPinBase64(String ukeyPinBase64) {
|
||||
this.ukeyPinBase64 = ukeyPinBase64;
|
||||
}
|
||||
|
||||
public String getLoginPinBase64() {
|
||||
return loginPinBase64;
|
||||
}
|
||||
|
||||
public void setLoginPinBase64(String loginPinBase64) {
|
||||
this.loginPinBase64 = loginPinBase64;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoUkeyPinChangeInternalRequest {
|
||||
|
||||
@Min(0)
|
||||
private int pinType;
|
||||
|
||||
@NotBlank
|
||||
private String oldPinBase64;
|
||||
|
||||
@NotBlank
|
||||
private String newPinBase64;
|
||||
|
||||
public int getPinType() {
|
||||
return pinType;
|
||||
}
|
||||
|
||||
public void setPinType(int pinType) {
|
||||
this.pinType = pinType;
|
||||
}
|
||||
|
||||
public String getOldPinBase64() {
|
||||
return oldPinBase64;
|
||||
}
|
||||
|
||||
public void setOldPinBase64(String oldPinBase64) {
|
||||
this.oldPinBase64 = oldPinBase64;
|
||||
}
|
||||
|
||||
public String getNewPinBase64() {
|
||||
return newPinBase64;
|
||||
}
|
||||
|
||||
public void setNewPinBase64(String newPinBase64) {
|
||||
this.newPinBase64 = newPinBase64;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.cisd.tms.modules.device.dto.crypto.request;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class CryptoUkeyPinInternalRequest {
|
||||
|
||||
@NotBlank
|
||||
private String ukeyPinBase64;
|
||||
|
||||
public String getUkeyPinBase64() {
|
||||
return ukeyPinBase64;
|
||||
}
|
||||
|
||||
public void setUkeyPinBase64(String ukeyPinBase64) {
|
||||
this.ukeyPinBase64 = ukeyPinBase64;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user