Skip to content

Commit 7e21eee

Browse files
HatemMnManuthor
authored andcommitted
feat: add i18n french support
1 parent 26db139 commit 7e21eee

13 files changed

Lines changed: 2887 additions & 14 deletions

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ repos:
4646
rev: v1.31.1
4747
hooks:
4848
- id: typos
49-
exclude: documentation/docs/images/google_cse.drawio.svg|crate/test_server/src/test_jwt.rs|crate/pkcs11/documentation/veracrypt_ckms.svg|crate/server/src/tests/google_cse/|documentation/docs/pkcs11/images|documentation/docs/kms_clients/pkcs11/images|crate/server/resources|documentation/docs/algorithms.md|crate/server/src/tests/certificates/chain/root/ca/|documentation/docs/pki/smime.md|documentation/docs/hsms/proteccio.md|crate/crypto/src/crypto/rsa/ckm_rsa_aes_key_wrap.rs|crate/clients/ckms/src/tests/shared/export_import.rs|ui/src/Locate.tsx|kmip/|.mise/scripts/oracle/README_HSM.md|crate/pkcs11/documentation/veracrypt_ckms.svg|documentation/docs/pkcs11/images|nix/signing-keys/cosmian-kms-public.asc|sbom/|documentation/docs/certifications_and_compliance/cryptographic_algorithms/benchmarks/|crate/clients/clap/src/tests/shared/export_import.rs|crate/crypto/src/crypto/fpe/ff1.rs|documentation/docs/benchmarks/|.mise/scripts/bench/bench_run_flamegraph.sh|docs.instructions.md|crate/server/src/tests/jose/rfc_vectors.rs
49+
exclude: documentation/docs/images/google_cse.drawio.svg|crate/test_server/src/test_jwt.rs|crate/pkcs11/documentation/veracrypt_ckms.svg|crate/server/src/tests/google_cse/|documentation/docs/pkcs11/images|documentation/docs/kms_clients/pkcs11/images|crate/server/resources|documentation/docs/algorithms.md|crate/server/src/tests/certificates/chain/root/ca/|documentation/docs/pki/smime.md|documentation/docs/hsms/proteccio.md|crate/crypto/src/crypto/rsa/ckm_rsa_aes_key_wrap.rs|crate/clients/ckms/src/tests/shared/export_import.rs|ui/src/Locate.tsx|kmip/|.mise/scripts/oracle/README_HSM.md|crate/pkcs11/documentation/veracrypt_ckms.svg|documentation/docs/pkcs11/images|nix/signing-keys/cosmian-kms-public.asc|sbom/|documentation/docs/certifications_and_compliance/cryptographic_algorithms/benchmarks/|crate/clients/clap/src/tests/shared/export_import.rs|crate/crypto/src/crypto/fpe/ff1.rs|documentation/docs/benchmarks/|.mise/scripts/bench/bench_run_flamegraph.sh|docs.instructions.md|crate/server/src/tests/jose/rfc_vectors.rs|ui/src/i18n/locales/fr/|ui/src/i18n/locales/zh-CN
5050

5151
- repo: https://github.com/Lucas-C/pre-commit-hooks
5252
rev: v1.5.5

CHANGELOG/feat_french_kms.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Features
2+
3+
### UI
4+
5+
- Add French (`fr`) as a third supported UI locale alongside English and Simplified Chinese:
6+
- New "🇫🇷 Français" option in the header language switcher
7+
- Full translation of the sidebar menu, layout (header, footer, login, 404), `Locate` page, and every action form (`common`, `layout`, `locate`, `menu`, `actions` namespaces)
8+
- Ant Design components (date pickers, pagination, popconfirm, …) and `dayjs` now follow the French locale when selected
9+
- Terminology policy: cryptographic algorithms/standards (`RSA`, `AES`, `EC`, `PQC`, `Covercrypt`, `MAC`, `FPE`, `HSM`, `KEK`, `BYOK`, `ML-KEM`, `ML-DSA`, `SLH-DSA`, …) are kept untranslated; business/user-facing copy is translated. "Chiffrer/Déchiffrer" is used consistently for encrypt/decrypt (never "crypter/décrypter")
10+
11+
## Refactoring
12+
13+
### UI
14+
15+
- Extract a `localeRegistry.ts` module as the single source of truth for per-locale configuration (label, Ant Design locale, `dayjs` locale, browser-language matcher, translation bundle). `i18n/index.ts`, `useAppLocale.ts`, and `LanguageSwitcher.tsx` now derive from this registry instead of hardcoding each locale — adding a future locale is a single registry entry plus its JSON bundle

crate/test_kms_server/src/crl_tests.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,3 +1121,90 @@ async fn test_crl_invalid_format_returns_400() {
11211121

11221122
resources.cleanup(&client).await;
11231123
}
1124+
1125+
/// Retrieve the `PrivateKeyLink` attribute from a certificate to get the CA signing key ID.
1126+
async fn get_linked_private_key_id(client: &KmsClient, cert_id: &str) -> String {
1127+
client
1128+
.get_attributes(GetAttributes::from(cert_id))
1129+
.await
1130+
.expect("GetAttributes should succeed")
1131+
.attributes
1132+
.get_link(LinkType::PrivateKeyLink)
1133+
.expect("certificate must have a PrivateKeyLink attribute")
1134+
.to_string()
1135+
}
1136+
1137+
/// Test: CRL must include revoked certificates regardless of which user owns them.
1138+
///
1139+
/// RFC 5280 §5.1 requires a CRL to list every certificate issued by the CA that
1140+
/// has been revoked, irrespective of who owns the certificate in the KMS database.
1141+
///
1142+
/// **Regression guard** for the `find_all` fix: prior to the fix, `find_revoked_certificates`
1143+
/// used a user-scoped `find()` call. Because `find()` only returns objects accessible to
1144+
/// the requesting user, certificates owned by other users were silently omitted.
1145+
/// If the fix is reverted, this test fails with `"expected 3, got 1"`.
1146+
///
1147+
/// Setup (cert-auth server — owner and user are distinct DB identities):
1148+
/// - `owner.client@acme.com` creates CA, issues leaf-1 → DB owner = owner
1149+
/// - `user.client@acme.com` issues leaf-2, leaf-3 → DB owner = user
1150+
/// - All 3 revoked
1151+
/// - Owner generates CRL → must contain all 3 serial numbers
1152+
#[tokio::test]
1153+
async fn test_crl_contains_certs_from_all_users() {
1154+
init_test_logging();
1155+
// Use mTLS cert-auth server: owner and user are distinct DB identities.
1156+
// The cert-auth server has no CO configured, so generate_crl is accessible
1157+
// to the object owner (owner.client@acme.com owns the CA).
1158+
let ctx = start_default_test_kms_server_with_cert_auth().await;
1159+
let owner = ctx.get_owner_client();
1160+
let user = ctx.get_user_client();
1161+
let mut resources = TestResources::new();
1162+
1163+
// 1. Owner creates CA (owner.client@acme.com owns the CA cert and CA private key)
1164+
let ca_id = create_named_ca(&owner, "MultiOwner-CRL-CA", &mut resources).await;
1165+
let ca_sk_id = get_linked_private_key_id(&owner, &ca_id).await;
1166+
resources.track(ca_sk_id.clone());
1167+
1168+
// 2. Grant user.client@acme.com the Certify permission on both the CA cert and CA
1169+
// private key so they can issue leaf certificates without being the owner.
1170+
// The server resolves the issuer private key via PrivateKeyLink and calls
1171+
// retrieve_object_for_operation(KmipOperation::Certify) on each.
1172+
for uid in [&ca_id, &ca_sk_id] {
1173+
owner
1174+
.grant_access(Access {
1175+
unique_identifier: Some(UniqueIdentifier::TextString(uid.clone())),
1176+
user_id: "user.client@acme.com".to_owned(),
1177+
operation_types: vec![KmipOperation::Certify],
1178+
})
1179+
.await
1180+
.expect("grant Certify access should succeed");
1181+
}
1182+
1183+
// 3. Owner issues leaf-1 (DB owner = owner.client@acme.com)
1184+
let leaf1 = issue_cert(&owner, &ca_id, "leaf1.multi-owner-crl", &mut resources).await;
1185+
1186+
// 4. User issues leaf-2 and leaf-3 (DB owner = user.client@acme.com)
1187+
let leaf2 = issue_cert(&user, &ca_id, "leaf2.multi-owner-crl", &mut resources).await;
1188+
let leaf3 = issue_cert(&user, &ca_id, "leaf3.multi-owner-crl", &mut resources).await;
1189+
1190+
// 5. Revoke all three certificates
1191+
revoke_cert(&owner, &leaf1, RevocationReasonCode::Superseded).await;
1192+
revoke_cert(&user, &leaf2, RevocationReasonCode::Superseded).await;
1193+
revoke_cert(&user, &leaf3, RevocationReasonCode::KeyCompromise).await;
1194+
1195+
// 6. Owner generates CRL for the CA.
1196+
// With find_all: sees all 3 revoked certs regardless of DB ownership → len == 3.
1197+
// Without fix (find scoped to owner): only sees leaf-1 → len == 1, assertion fails.
1198+
let crl = fetch_crl_der(&owner, &ca_id, 7).await;
1199+
let revoked = crl.get_revoked().expect("CRL must contain revoked entries");
1200+
1201+
assert_eq!(
1202+
revoked.len(),
1203+
3,
1204+
"CRL must contain all 3 revoked certificates regardless of DB owner: \
1205+
leaf-1 (owned by owner.client@acme.com) + \
1206+
leaf-2 + leaf-3 (both owned by user.client@acme.com)"
1207+
);
1208+
1209+
resources.cleanup(&owner).await;
1210+
}

0 commit comments

Comments
 (0)