feat:补充算法校验
This commit is contained in:
@@ -193,6 +193,21 @@ mvn -q -DskipTests compile
|
||||
mvn -q test
|
||||
```
|
||||
|
||||
## PCIe Real-Card Smoke
|
||||
|
||||
- Checklist: `docs/plans/2026-02-28-pcie-realcard-smoke-checklist.md`
|
||||
- Script template: `scripts/pcie_realcard_smoke.sh`
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
export BASE_URL=http://127.0.0.1:8080
|
||||
export INTERNAL_TOKEN=change-me-internal-token
|
||||
export ALG_SM3=1
|
||||
export ALG_SM4_ECB=1025
|
||||
./scripts/pcie_realcard_smoke.sh
|
||||
```
|
||||
|
||||
- CI is pinned to JDK 17 via `.github/workflows/ci.yml`.
|
||||
- Maven Surefire preloads Mockito javaagent to avoid dynamic self-attach failures on newer JDKs.
|
||||
|
||||
@@ -203,4 +218,3 @@ mvn -q test
|
||||
- Basic auth interceptors for internal/openapi are in place.
|
||||
- `init/auth/device/sign/system` modules have runnable skeleton controllers and services.
|
||||
- `init/auth/device` modules include mapper+xml+repository-impl+DDL skeleton for TiDB.
|
||||
>>>>>>> aeb6a4d (初始化项目)
|
||||
|
||||
@@ -14,6 +14,7 @@ public class CryptoCardProperties {
|
||||
private Mode mode = Mode.MOCK;
|
||||
private String vendorLibPath;
|
||||
private String vendorLibName = "swsdsdf";
|
||||
private boolean strictAlgIdValidation = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
@@ -46,4 +47,12 @@ public class CryptoCardProperties {
|
||||
public void setVendorLibName(String vendorLibName) {
|
||||
this.vendorLibName = vendorLibName;
|
||||
}
|
||||
|
||||
public boolean isStrictAlgIdValidation() {
|
||||
return strictAlgIdValidation;
|
||||
}
|
||||
|
||||
public void setStrictAlgIdValidation(boolean strictAlgIdValidation) {
|
||||
this.strictAlgIdValidation = strictAlgIdValidation;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -25,8 +25,11 @@ public class PcieCryptoServiceConfiguration {
|
||||
}
|
||||
|
||||
if (properties.getMode() == CryptoCardProperties.Mode.JNA) {
|
||||
log.info("PCIe crypto service enabled in JNA mode");
|
||||
return new JnaPcieCryptoService(sessionTemplate);
|
||||
log.info(
|
||||
"PCIe crypto service enabled in JNA mode, strictAlgIdValidation={}",
|
||||
properties.isStrictAlgIdValidation()
|
||||
);
|
||||
return new JnaPcieCryptoService(sessionTemplate, properties);
|
||||
}
|
||||
|
||||
log.info("PCIe crypto service fallback to mock, current mode={}", properties.getMode());
|
||||
|
||||
+255
-166
@@ -1,5 +1,7 @@
|
||||
package com.cisd.tms.integration.crypto.pcie.service;
|
||||
|
||||
import com.cisd.tms.integration.crypto.config.CryptoCardProperties;
|
||||
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
|
||||
import com.cisd.tms.integration.crypto.pcie.PcieCryptoException;
|
||||
import com.cisd.tms.integration.crypto.pcie.PcieKeyState;
|
||||
import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate;
|
||||
@@ -91,9 +93,11 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
private static final int ECC_CIPHER_PREFIX_LENGTH = (EccRefPublicKey.MAX_LEN * 2) + 32 + Integer.BYTES;
|
||||
|
||||
private final PcieSessionTemplate sessionTemplate;
|
||||
private final boolean strictAlgIdValidation;
|
||||
|
||||
public JnaPcieCryptoService(PcieSessionTemplate sessionTemplate) {
|
||||
public JnaPcieCryptoService(PcieSessionTemplate sessionTemplate, CryptoCardProperties properties) {
|
||||
this.sessionTemplate = sessionTemplate;
|
||||
this.strictAlgIdValidation = properties.isStrictAlgIdValidation();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,13 +173,18 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] oldPinValue = requireNonEmptyBytes("oldPin", oldPin);
|
||||
byte[] newPinValue = requireNonEmptyBytes("newPin", newPin);
|
||||
|
||||
sessionTemplate.withSession("SDFE_InitIdentify", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_InitIdentify",
|
||||
lib.SDFE_InitIdentify(sessionHandle, oldPinValue, oldPinValue.length, newPinValue, newPinValue.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_InitIdentify", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_InitIdentify",
|
||||
lib.SDFE_InitIdentify(sessionHandle, oldPinValue, oldPinValue.length, newPinValue, newPinValue.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(oldPinValue);
|
||||
wipe(newPinValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -216,20 +225,25 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] oldPassword = requireNonEmptyBytes("oldPassword", req.getOldPassword());
|
||||
byte[] newPassword = requireNonEmptyBytes("newPassword", req.getNewPassword());
|
||||
|
||||
sessionTemplate.withSession("SDFE_ChangePrivateKeyAccessPassword", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ChangePrivateKeyAccessPassword",
|
||||
lib.SDFE_ChangePrivateKeyAccessPassword(
|
||||
sessionHandle,
|
||||
keyIndex,
|
||||
oldPassword,
|
||||
oldPassword.length,
|
||||
newPassword,
|
||||
newPassword.length
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_ChangePrivateKeyAccessPassword", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ChangePrivateKeyAccessPassword",
|
||||
lib.SDFE_ChangePrivateKeyAccessPassword(
|
||||
sessionHandle,
|
||||
keyIndex,
|
||||
oldPassword,
|
||||
oldPassword.length,
|
||||
newPassword,
|
||||
newPassword.length
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(oldPassword);
|
||||
wipe(newPassword);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -238,13 +252,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
|
||||
byte[] password = requireNonEmptyBytes("password", req.getPassword());
|
||||
|
||||
sessionTemplate.withSession("SDF_GetPrivateKeyAccessRight", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDF_GetPrivateKeyAccessRight",
|
||||
lib.SDF_GetPrivateKeyAccessRight(sessionHandle, keyIndex, password, password.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDF_GetPrivateKeyAccessRight", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDF_GetPrivateKeyAccessRight",
|
||||
lib.SDF_GetPrivateKeyAccessRight(sessionHandle, keyIndex, password, password.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(password);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -352,13 +370,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
|
||||
byte[] keyData = requireNonEmptyBytes("keyData", req.getKeyData());
|
||||
|
||||
sessionTemplate.withSession("SDFE_ImportKEK", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ImportKEK",
|
||||
lib.SDFE_ImportKEK(sessionHandle, keyIndex, keyData, keyData.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_ImportKEK", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ImportKEK",
|
||||
lib.SDFE_ImportKEK(sessionHandle, keyIndex, keyData, keyData.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(keyData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -426,20 +448,24 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
throw new IllegalArgumentException("storeFlag must be 0 or 1");
|
||||
}
|
||||
|
||||
sessionTemplate.withSession("SDFE_RecoverUserKey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_RecoverUserKey",
|
||||
lib.SDFE_RecoverUserKey(
|
||||
sessionHandle,
|
||||
keyIndex,
|
||||
keyType,
|
||||
encryptedKey,
|
||||
encryptedKey.length,
|
||||
(byte) storeFlag
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_RecoverUserKey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_RecoverUserKey",
|
||||
lib.SDFE_RecoverUserKey(
|
||||
sessionHandle,
|
||||
keyIndex,
|
||||
keyType,
|
||||
encryptedKey,
|
||||
encryptedKey.length,
|
||||
(byte) storeFlag
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(encryptedKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -461,13 +487,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
|
||||
byte[] encryptedKey = requireNonEmptyBytes("encryptedKey", req.getEncryptedKey());
|
||||
|
||||
sessionTemplate.withSession("SDFE_RecoverKEK", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_RecoverKEK",
|
||||
lib.SDFE_RecoverKEK(sessionHandle, keyIndex, encryptedKey, encryptedKey.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_RecoverKEK", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_RecoverKEK",
|
||||
lib.SDFE_RecoverKEK(sessionHandle, keyIndex, encryptedKey, encryptedKey.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(encryptedKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -506,13 +536,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
public void restoreAllKey(byte[] keyImage) {
|
||||
byte[] safeKeyImage = requireNonEmptyBytes("keyImage", keyImage);
|
||||
|
||||
sessionTemplate.withSession("SDFE_RestoryKey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_RestoryKey",
|
||||
lib.SDFE_RestoryKey(sessionHandle, safeKeyImage, safeKeyImage.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_RestoryKey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_RestoryKey",
|
||||
lib.SDFE_RestoryKey(sessionHandle, safeKeyImage, safeKeyImage.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(safeKeyImage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -563,10 +597,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
EnvelopedKeyBlob blob = toEnvelopedKeyBlob("envelopedKeyBlob", req.getEnvelopedKeyBlob());
|
||||
|
||||
sessionTemplate.withSession("SDFE_ImportEncKeyPair_ECC", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ImportEncKeyPair_ECC",
|
||||
lib.SDFE_ImportEncKeyPair_ECC(sessionHandle, keyIndex, blob)
|
||||
);
|
||||
sessionTemplate.ensureSuccess("SDFE_ImportEncKeyPair_ECC", lib.SDFE_ImportEncKeyPair_ECC(sessionHandle, keyIndex, blob));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -575,25 +606,30 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
public void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request) {
|
||||
ImportEncKeyPairRsaRequest req = requireRequest("request", request);
|
||||
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
|
||||
int symAlgId = requirePositive("symAlgId", req.getSymAlgId());
|
||||
int symAlgId = requireValidAlgId("symAlgId", req.getSymAlgId());
|
||||
byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
|
||||
byte[] encryptedData = requireNonEmptyBytes("encryptedData", req.getEncryptedData());
|
||||
|
||||
sessionTemplate.withSession("SDFE_ImportEncKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ImportEncKeyPair_RSA",
|
||||
lib.SDFE_ImportEncKeyPair_RSA(
|
||||
sessionHandle,
|
||||
keyIndex,
|
||||
symAlgId,
|
||||
wrappedKey,
|
||||
wrappedKey.length,
|
||||
encryptedData,
|
||||
encryptedData.length
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_ImportEncKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ImportEncKeyPair_RSA",
|
||||
lib.SDFE_ImportEncKeyPair_RSA(
|
||||
sessionHandle,
|
||||
keyIndex,
|
||||
symAlgId,
|
||||
wrappedKey,
|
||||
wrappedKey.length,
|
||||
encryptedData,
|
||||
encryptedData.length
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(wrappedKey);
|
||||
wipe(encryptedData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -716,7 +752,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request) {
|
||||
GenerateStandardEccKeyPairRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
int keyBits = requirePositive("keyBits", req.getKeyBits());
|
||||
int publicKeySize = requirePositive("publicKeyBufferSize", req.getPublicKeyBufferSize());
|
||||
int privateKeySize = requirePositive("privateKeyBufferSize", req.getPrivateKeyBufferSize());
|
||||
@@ -742,7 +778,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
public BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request) {
|
||||
GenerateKeyWithKekRequest req = requireRequest("request", request);
|
||||
int keyBits = requirePositive("keyBits", req.getKeyBits());
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
|
||||
@@ -989,7 +1025,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
public BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request) {
|
||||
GenerateKeyWithEpkEccRequest req = requireRequest("request", request);
|
||||
int keyBits = requirePositive("keyBits", req.getKeyBits());
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
|
||||
@@ -1067,7 +1103,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
public BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request) {
|
||||
ExchangeDigitEnvelopeEccRequest req = requireRequest("request", request);
|
||||
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
|
||||
EccCipher inputEnvelopeBlob = toEccCipher("inputEnvelopeBlob", req.getInputEnvelopeBlob());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
@@ -1213,6 +1249,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
result.setSponsorPublicKeyLength(sponsorPublicKeyBytes.length);
|
||||
result.setSponsorTmpPublicKey(sponsorTmpPublicKeyBytes);
|
||||
result.setSponsorTmpPublicKeyLength(sponsorTmpPublicKeyBytes.length);
|
||||
// SDF_GenerateKeyWithECC returns a session key handle, not plaintext key bytes.
|
||||
result.setSessionKey(new byte[0]);
|
||||
result.setSessionKeyLength(0);
|
||||
result.setSessionKeyGenerated(keyHandleRef.getValue() != null);
|
||||
@@ -1247,7 +1284,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
|
||||
EccExternalSignRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
int signatureBufferSize = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
|
||||
@@ -1285,7 +1322,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public void eccExternalVerify(EccExternalVerifyRequest request) {
|
||||
EccExternalVerifyRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
EccSignature signature = toEccSignature("signature", req.getSignature());
|
||||
@@ -1302,7 +1339,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request) {
|
||||
EccExternalEncryptRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
@@ -1324,7 +1361,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request) {
|
||||
EccExternalDecryptRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob());
|
||||
EccCipher encryptedData = toEccCipher("encryptedData", req.getEncryptedData());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
@@ -1343,7 +1380,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request) {
|
||||
SymmetricCryptoRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
byte[] key = requireNonEmptyBytes("key", req.getKey());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
@@ -1365,7 +1402,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request) {
|
||||
SymmetricCryptoRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
byte[] key = requireNonEmptyBytes("key", req.getKey());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
@@ -1387,7 +1424,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
|
||||
SymmetricKekCryptoRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
|
||||
byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
@@ -1410,7 +1447,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
|
||||
SymmetricKekCryptoRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
|
||||
byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
@@ -1433,7 +1470,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult calculateMacWithPlainKey(MacCalcRequest request) {
|
||||
MacCalcRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
byte[] key = requireNonEmptyBytes("key", req.getKey());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
@@ -1455,7 +1492,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public BackupDataResult digest(DigestRequest request) {
|
||||
DigestRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
|
||||
|
||||
@@ -1474,30 +1511,34 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
@Override
|
||||
public HmacResult hmac(HmacRequest request) {
|
||||
HmacRequest req = requireRequest("request", request);
|
||||
int algId = requirePositive("algId", req.getAlgId());
|
||||
int algId = requireValidAlgId("algId", req.getAlgId());
|
||||
byte[] key = requireNonEmptyBytes("key", req.getKey());
|
||||
byte[] data = requireBytes("data", req.getData());
|
||||
|
||||
return sessionTemplate.withSession("SDFE_Hmac", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_HmacInit", lib.SDFE_HmacInit(sessionHandle, algId, key, key.length));
|
||||
if (data.length > 0) {
|
||||
sessionTemplate.ensureSuccess("SDFE_HmacUpdate", lib.SDFE_HmacUpdate(sessionHandle, data, data.length));
|
||||
}
|
||||
try {
|
||||
return sessionTemplate.withSession("SDFE_Hmac", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_HmacInit", lib.SDFE_HmacInit(sessionHandle, algId, key, key.length));
|
||||
if (data.length > 0) {
|
||||
sessionTemplate.ensureSuccess("SDFE_HmacUpdate", lib.SDFE_HmacUpdate(sessionHandle, data, data.length));
|
||||
}
|
||||
|
||||
byte[] out = new byte[HMAC_MAX_LENGTH];
|
||||
IntByReference outLen = new IntByReference(out.length);
|
||||
sessionTemplate.ensureSuccess("SDFE_HmacFinal", lib.SDFE_HmacFinal(sessionHandle, out, outLen));
|
||||
byte[] out = new byte[HMAC_MAX_LENGTH];
|
||||
IntByReference outLen = new IntByReference(out.length);
|
||||
sessionTemplate.ensureSuccess("SDFE_HmacFinal", lib.SDFE_HmacFinal(sessionHandle, out, outLen));
|
||||
|
||||
int length = outLen.getValue();
|
||||
if (length <= 0 || length > out.length) {
|
||||
throw new PcieCryptoException("SDFE_HmacFinal", -1, "native returned invalid HMAC length: " + length);
|
||||
}
|
||||
int length = outLen.getValue();
|
||||
if (length <= 0 || length > out.length) {
|
||||
throw new PcieCryptoException("SDFE_HmacFinal", -1, "native returned invalid HMAC length: " + length);
|
||||
}
|
||||
|
||||
HmacResult result = new HmacResult();
|
||||
result.setHmacLength(length);
|
||||
result.setHmac(Arrays.copyOf(out, length));
|
||||
return result;
|
||||
});
|
||||
HmacResult result = new HmacResult();
|
||||
result.setHmacLength(length);
|
||||
result.setHmac(Arrays.copyOf(out, length));
|
||||
return result;
|
||||
});
|
||||
} finally {
|
||||
wipe(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1641,20 +1682,25 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
|
||||
byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin());
|
||||
|
||||
sessionTemplate.withSession("SDFE_GenerateUkey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_GenerateUkey",
|
||||
lib.SDFE_GenerateUkey(
|
||||
sessionHandle,
|
||||
(byte) adminIndex,
|
||||
ukeyPin,
|
||||
ukeyPin.length,
|
||||
loginPin,
|
||||
loginPin.length
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_GenerateUkey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_GenerateUkey",
|
||||
lib.SDFE_GenerateUkey(
|
||||
sessionHandle,
|
||||
(byte) adminIndex,
|
||||
ukeyPin,
|
||||
ukeyPin.length,
|
||||
loginPin,
|
||||
loginPin.length
|
||||
)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(ukeyPin);
|
||||
wipe(loginPin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1663,13 +1709,18 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
|
||||
byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin());
|
||||
|
||||
sessionTemplate.withSession("SDFE_LoginUkey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_LoginUkey",
|
||||
lib.SDFE_LoginUkey(sessionHandle, ukeyPin, ukeyPin.length, loginPin, loginPin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_LoginUkey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_LoginUkey",
|
||||
lib.SDFE_LoginUkey(sessionHandle, ukeyPin, ukeyPin.length, loginPin, loginPin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(ukeyPin);
|
||||
wipe(loginPin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1679,13 +1730,18 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] oldPin = requireNonEmptyBytes("oldPin", req.getOldPin());
|
||||
byte[] newPin = requireNonEmptyBytes("newPin", req.getNewPin());
|
||||
|
||||
sessionTemplate.withSession("SDFE_ChangeUkeyPin", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ChangeUkeyPin",
|
||||
lib.SDFE_ChangeUkeyPin(sessionHandle, pinType, oldPin, oldPin.length, newPin, newPin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_ChangeUkeyPin", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ChangeUkeyPin",
|
||||
lib.SDFE_ChangeUkeyPin(sessionHandle, pinType, oldPin, oldPin.length, newPin, newPin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(oldPin);
|
||||
wipe(newPin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1694,23 +1750,32 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
byte[] adminPin = requireNonEmptyBytes("adminPin", req.getAdminPin());
|
||||
byte[] userPin = requireNonEmptyBytes("userPin", req.getUserPin());
|
||||
|
||||
sessionTemplate.withSession("SDFE_UnlockUkey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_UnlockUkey",
|
||||
lib.SDFE_UnlockUkey(sessionHandle, adminPin, adminPin.length, userPin, userPin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_UnlockUkey", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_UnlockUkey",
|
||||
lib.SDFE_UnlockUkey(sessionHandle, adminPin, adminPin.length, userPin, userPin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(adminPin);
|
||||
wipe(userPin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readLmkComponent(byte[] ukeyPin) {
|
||||
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
|
||||
|
||||
sessionTemplate.withSession("SDFE_ReadLMKComponent", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_ReadLMKComponent", lib.SDFE_ReadLMKComponent(sessionHandle, pin, pin.length));
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_ReadLMKComponent", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_ReadLMKComponent", lib.SDFE_ReadLMKComponent(sessionHandle, pin, pin.length));
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(pin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1718,23 +1783,31 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
int safeKeyType = requireNonNegative("keyType", keyType);
|
||||
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
|
||||
|
||||
sessionTemplate.withSession("SDFE_ReadUkeyIKComponent", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ReadUkeyIKComponent",
|
||||
lib.SDFE_ReadUkeyIKComponent(sessionHandle, safeKeyType, pin, pin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_ReadUkeyIKComponent", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess(
|
||||
"SDFE_ReadUkeyIKComponent",
|
||||
lib.SDFE_ReadUkeyIKComponent(sessionHandle, safeKeyType, pin, pin.length)
|
||||
);
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(pin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateCertificate(byte[] ukeyPin) {
|
||||
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
|
||||
|
||||
sessionTemplate.withSession("SDFE_GenerateCertificate", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_GenerateCertificate", lib.SDFE_GenerateCertificate(sessionHandle, pin, pin.length));
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
sessionTemplate.withSession("SDFE_GenerateCertificate", (lib, deviceHandle, sessionHandle) -> {
|
||||
sessionTemplate.ensureSuccess("SDFE_GenerateCertificate", lib.SDFE_GenerateCertificate(sessionHandle, pin, pin.length));
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
wipe(pin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1835,6 +1908,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
return callback.apply(keyHandle);
|
||||
} finally {
|
||||
destroyKeyHandle(lib, sessionHandle, keyHandle);
|
||||
wipe(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1856,6 +1930,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
return callback.apply(keyHandle);
|
||||
} finally {
|
||||
destroyKeyHandle(lib, sessionHandle, keyHandle);
|
||||
wipe(wrappedKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1943,6 +2018,20 @@ public class JnaPcieCryptoService implements PcieCryptoService {
|
||||
return value;
|
||||
}
|
||||
|
||||
private int requireValidAlgId(String name, int algId) {
|
||||
int value = requirePositive(name, algId);
|
||||
if (strictAlgIdValidation && !Gm0018AlgorithmIds.isSupported(value)) {
|
||||
throw new IllegalArgumentException(name + " is not a supported GM/T 0018 algorithm id: 0x" + Integer.toHexString(value));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static void wipe(byte[] value) {
|
||||
if (value != null) {
|
||||
Arrays.fill(value, (byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] requireNonEmptyBytes(String name, byte[] value) {
|
||||
if (value == null || value.length == 0) {
|
||||
throw new IllegalArgumentException(name + " must not be empty");
|
||||
|
||||
@@ -38,3 +38,4 @@ tms:
|
||||
mode: ${TMS_CRYPTO_CARD_MODE:MOCK}
|
||||
vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:}
|
||||
vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:swsdsdf}
|
||||
strict-alg-id-validation: ${TMS_CRYPTO_STRICT_ALG_ID_VALIDATION:true}
|
||||
|
||||
Reference in New Issue
Block a user