Categoria: Infrastruttura PKI
Complessità: Alta
Prerequisiti: Nessuno (punto di ingresso)
Tempo stimato: 15-30 minuti
Questo scenario descrive la creazione di una Root-CA autofirmata con chiavi Post-Quantum. La Root-CA costituisce l'ancora di fiducia (Trust Anchor) per l'intera gerarchia PKI ed è l'elemento più critico per la sicurezza dell'infrastruttura.
Cosa viene creato:
Casi d'uso:
┌─────────────────────────────────────────────────────────────────┐
│ CREAZIONE ROOT-CA │
└─────────────────────────────────────────────────────────────────┘
┌──────────────┐
│ 1. Init │
│ Libreria │
└──────┬───────┘
│
▼
┌──────────────┐
│ 2. KeyPair │ ──────► ML-DSA-65 (FIPS 204)
│ generare │ ~4KB Chiave pubblica
└──────┬───────┘ ~2KB Chiave privata
│
▼
┌──────────────┐
│ 3. DN │ ──────► CN=WvdS Root CA
│ creare │ O=DATECpro GmbH
└──────┬───────┘ C=DE
│
▼
┌──────────────┐
│ 4. Serial │ ──────► 20 Bytes casuali (160 bit)
│ generare │
└──────┬───────┘
│
▼
┌──────────────┐
│ 5. Validity │ ──────► notBefore: adesso
│ definire │ notAfter: +20 anni
└──────┬───────┘
│
▼
┌──────────────┐
│ 6. Extensions│ ──────► BasicConstraints: CA=true, pathLen=1
│ impostare │ KeyUsage: keyCertSign, cRLSign
└──────┬───────┘ SKI: SHA-256(publicKey)
│
▼
┌──────────────┐
│ 7. Certificato│ ──────► Subject = Issuer (autofirmato)
│ creare │ Firma con ML-DSA-65
└──────┬───────┘
│
▼
┌──────────────┐
│ 8. Export │ ──────► root-ca.crt.pem (Certificato)
│ PEM │ root-ca.key.pem (crittografato)
└──────┬───────┘
│
▼
┌──────────────┐
│ 9. Cleanup │ ──────► Rilasciare handle
│ │ Azzerare secret
└──────────────┘
| Passo | Funzione FFI | Crate Rust | Descrizione |
|---|---|---|---|
| 1 | wvds_sec_crypto_x509_init() | std::sync | Inizializzare libreria |
| 2 | wvds_sec_crypto_x509_keypair_generate_mldsa(65) | ml-dsa | Coppia chiavi ML-DSA-65 |
| 2a | wvds_sec_crypto_x509_keypair_self_test() | ml-dsa | Autotest (sign/verify) |
| 3a | wvds_sec_crypto_x509_dn_create() | x509-cert | Creare handle DN |
| 3b | wvds_sec_crypto_x509_dn_add_component() | x509-cert, der | Aggiungere CN, O, C |
| 4 | wvds_sec_crypto_x509_serial_generate() | rand | Numero seriale 160-bit |
| 5 | wvds_sec_crypto_x509_validity_create() | x509-cert | Periodo di validità |
| 6a | wvds_sec_crypto_x509_ext_set_basic_constraints() | x509-cert, der | CA=true, pathLen |
| 6b | wvds_sec_crypto_x509_ext_set_key_usage() | x509-cert, der | keyCertSign, cRLSign |
| 6c | wvds_sec_crypto_x509_ext_set_ski_from_keypair() | sha2 | Subject Key Identifier |
| 7 | wvds_sec_crypto_x509_cert_create_root() | x509-cert, ml-dsa | Creare certificato Root |
| 8a | wvds_sec_crypto_x509_cert_to_pem() | pem-rfc7468 | Certificato come PEM |
| 8b | wvds_sec_crypto_x509_keypair_to_pem_encrypted() | argon2, aes-gcm | Chiave crittografata |
| 9a | wvds_sec_crypto_x509_free_*() | std::alloc | Rilasciare handle |
| 9b | wvds_sec_crypto_x509_zeroize_keypair() | zeroize | Cancellare secret |
wvds_sec_crypto_x509_init()
│
├── wvds_sec_crypto_x509_keypair_generate_mldsa(level: u8) → *mut KeyPairHandle
│ │
│ ├── // Scelta parametri
│ │ ├── [ML_DSA_44] → ml_dsa::ml_dsa_44::KeyPair::generate(&mut OsRng)
│ │ ├── [ML_DSA_65] → ml_dsa::ml_dsa_65::KeyPair::generate(&mut OsRng) ✓
│ │ └── [ML_DSA_87] → ml_dsa::ml_dsa_87::KeyPair::generate(&mut OsRng)
│ │
│ ├── // Autotest (requisito FIPS)
│ │ ├── test_msg = [0x00..0x20] // 32 Bytes dati di test
│ │ ├── signature = signing_key.sign(&test_msg)
│ │ └── assert!(verifying_key.verify(&test_msg, &signature).is_ok())
│ │
│ └── // Creare handle
│ └── Box::into_raw(Box::new(KeyPairHandle {
│ algorithm: ML_DSA_65,
│ signing_key,
│ verifying_key
│ }))
│
├── wvds_sec_crypto_x509_dn_create() → *mut DnHandle
│ └── x509_cert::name::Name::default()
│
├── wvds_sec_crypto_x509_dn_add_component(dn, oid, value) → i32
│ │
│ ├── [OID_CN = "2.5.4.3"]
│ │ └── dn.0.push(RelativeDistinguishedName::from(
│ │ AttributeTypeAndValue { oid: OID_CN, value: "WvdS Root CA" }
│ │ ))
│ │
│ ├── [OID_O = "2.5.4.10"]
│ │ └── dn.0.push(..., value: "DATECpro GmbH")
│ │
│ └── [OID_C = "2.5.4.6"]
│ └── dn.0.push(..., value: "DE")
│
├── wvds_sec_crypto_x509_serial_generate(out: *mut u8, len: usize) → i32
│ │
│ ├── // RFC 5280: max 20 Bytes, positivo
│ │ └── rand::rngs::OsRng.fill_bytes(&mut serial[0..len])
│ │
│ └── // Impostare bit più alto a 0 (positivo)
│ └── serial[0] &= 0x7F
│
├── wvds_sec_crypto_x509_validity_create(not_before, not_after) → *mut ValidityHandle
│ │
│ ├── not_before = x509_cert::time::Time::UtcTime(now)
│ │
│ └── not_after = x509_cert::time::Time::GeneralizedTime(now + 20 years)
│ │
│ └── // GeneralizedTime per date >= 2050
│
├── wvds_sec_crypto_x509_ext_set_basic_constraints(ext, ca: bool, path_len: i32) → i32
│ │
│ ├── bc = x509_cert::ext::pkix::BasicConstraints {
│ │ ca: true,
│ │ path_len_constraint: Some(1) // solo 1 livello Intermediate
│ │ }
│ │
│ └── ext.add(Extension {
│ extn_id: OID_BASIC_CONSTRAINTS,
│ critical: true, // DEVE essere critical per CA
│ extn_value: der::Encode::to_der(&bc)
│ })
│
├── wvds_sec_crypto_x509_ext_set_key_usage(ext, flags: u16) → i32
│ │
│ ├── // Per Root-CA: keyCertSign (5) + cRLSign (6)
│ │ └── flags = 0x0006 // Bit 5 + Bit 6
│ │
│ ├── ku = x509_cert::ext::pkix::KeyUsage(flags)
│ │
│ └── ext.add(Extension {
│ extn_id: OID_KEY_USAGE,
│ critical: true, // DOVREBBE essere critical
│ extn_value: der::Encode::to_der(&ku)
│ })
│
├── wvds_sec_crypto_x509_ext_set_ski_from_keypair(ext, keypair) → i32
│ │
│ ├── // Subject Key Identifier = SHA-256(SubjectPublicKeyInfo.subjectPublicKey)
│ │ ├── public_key_bytes = keypair.verifying_key.to_bytes()
│ │ └── ski = sha2::Sha256::digest(&public_key_bytes)[0..20]
│ │
│ └── ext.add(Extension {
│ extn_id: OID_SUBJECT_KEY_ID,
│ critical: false,
│ extn_value: der::Encode::to_der(&OctetString::new(ski))
│ })
│
├── wvds_sec_crypto_x509_cert_create_root(
│ keypair: *const KeyPairHandle,
│ subject: *const DnHandle,
│ serial: *const u8,
│ serial_len: usize,
│ validity: *const ValidityHandle,
│ extensions: *const ExtHandle
│ ) → *mut CertHandle
│ │
│ ├── // Costruire TBSCertificate
│ │ └── tbs = x509_cert::TbsCertificate {
│ │ version: Version::V3,
│ │ serial_number: SerialNumber::new(&serial[..serial_len]),
│ │ signature: AlgorithmIdentifier { oid: OID_ML_DSA_65, parameters: None },
│ │ issuer: subject.clone(), // autofirmato: issuer = subject
│ │ validity: validity.clone(),
│ │ subject: subject.clone(),
│ │ subject_public_key_info: keypair.to_spki(),
│ │ extensions: Some(extensions.clone())
│ │ }
│ │
│ ├── // Codificare TBS-Certificate in DER
│ │ └── tbs_der = der::Encode::to_der(&tbs)
│ │
│ ├── // Firmare con ML-DSA-65
│ │ └── signature = ml_dsa::ml_dsa_65::SigningKey::sign(&tbs_der)
│ │ │
│ │ └── // Firma deterministica (FIPS 204)
│ │ // Lunghezza firma: 3293 Bytes
│ │
│ └── // Assemblare Certificate
│ └── cert = x509_cert::Certificate {
│ tbs_certificate: tbs,
│ signature_algorithm: AlgorithmIdentifier { oid: OID_ML_DSA_65 },
│ signature: BitString::from_bytes(&signature)
│ }
│
├── wvds_sec_crypto_x509_cert_to_pem(cert, out, out_len) → i32
│ │
│ ├── cert_der = der::Encode::to_der(&cert)
│ │
│ └── pem_rfc7468::encode_string("CERTIFICATE", &cert_der)
│ │
│ └── // Output esempio:
│ // -----BEGIN CERTIFICATE-----
│ // MIIxxxxxx...
│ // -----END CERTIFICATE-----
│
├── wvds_sec_crypto_x509_keypair_to_pem_encrypted(
│ keypair, password, kdf_algorithm, out, out_len
│ ) → i32
│ │
│ ├── // Chiave privata come PKCS#8 DER
│ │ └── private_key_der = keypair.signing_key.to_pkcs8_der()
│ │
│ ├── // Generare Salt e Nonce
│ │ ├── salt = rand::OsRng.gen::<[u8; 16]>()
│ │ └── nonce = rand::OsRng.gen::<[u8; 12]>()
│ │
│ ├── // Derivare Key Encryption Key
│ │ └── [ARGON2ID]
│ │ └── argon2::Argon2::new(
│ │ Algorithm::Argon2id,
│ │ Version::V0x13,
│ │ Params::new(65536, 3, 4, Some(32)) // 64MB, 3 Iter, 4 Lanes
│ │ ).hash_password_into(password.as_bytes(), &salt, &mut kek)
│ │
│ ├── // Crittografare chiave privata
│ │ └── encrypted = aes_gcm::Aes256Gcm::new(&kek)
│ │ .encrypt(&nonce, private_key_der.as_ref())
│ │
│ ├── // Creare EncryptedPrivateKeyInfo (PKCS#8)
│ │ └── epki = pkcs8::EncryptedPrivateKeyInfo {
│ │ encryption_algorithm: ...,
│ │ encrypted_data: encrypted
│ │ }
│ │
│ ├── // Codificare come PEM
│ │ └── pem_rfc7468::encode_string("ENCRYPTED PRIVATE KEY", &epki_der)
│ │
│ └── // Azzerare KEK
│ └── zeroize::Zeroize::zeroize(&mut kek)
│
└── // Cleanup
│
├── wvds_sec_crypto_x509_free_cert(cert)
├── wvds_sec_crypto_x509_free_keypair(keypair)
│ └── // Zeroize automatico via Drop
├── wvds_sec_crypto_x509_free_dn(dn)
├── wvds_sec_crypto_x509_free_validity(validity)
├── wvds_sec_crypto_x509_free_ext(ext)
└── wvds_sec_crypto_x509_shutdown()
using System; using System.IO; using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; namespace RootCaExample { class Program { static void Main(string[] args) { // Password per chiave privata (in produzione: inserire in modo sicuro!) string keyPassword = "MyStr0ng!RootCA#Password2024"; // 1. Inizializzare contesto using var context = PqCryptoContext.Initialize(); // 2. Generare coppia chiavi ML-DSA-65 Console.WriteLine("Generazione coppia chiavi ML-DSA-65..."); using var keyPair = context.GenerateKeyPair(PqAlgorithm.MlDsa65); // Eseguire autotest if (!keyPair.SelfTest()) throw new CryptographicException("KeyPair self-test failed!"); Console.WriteLine($" Chiave pubblica: {keyPair.PublicKeySize} Bytes"); Console.WriteLine($" Chiave privata: {keyPair.PrivateKeySize} Bytes"); // 3. Creare Distinguished Name var subjectDn = new DistinguishedNameBuilder() .AddCommonName("WvdS Root CA") .AddOrganization("DATECpro GmbH") .AddOrganizationalUnit("PQ-Security") .AddCountry("DE") .AddLocality("München") .Build(); Console.WriteLine($"Subject DN: {subjectDn}"); // 4. Periodo di validità (20 anni per Root-CA) var validity = new CertificateValidity( notBefore: DateTime.UtcNow, notAfter: DateTime.UtcNow.AddYears(20) ); // 5. Extensions per Root-CA var extensions = new X509ExtensionsBuilder() // BasicConstraints: CA=true, max 1 livello Intermediate .AddBasicConstraints(isCa: true, pathLengthConstraint: 1, critical: true) // KeyUsage: solo firma certificati e CRL .AddKeyUsage( KeyUsageFlags.KeyCertSign | KeyUsageFlags.CrlSign, critical: true ) // Subject Key Identifier per riferimento AKI successivo .AddSubjectKeyIdentifier(keyPair) .Build(); // 6. Creare certificato Root (autofirmato) Console.WriteLine("Creazione certificato Root autofirmato..."); using var rootCert = context.CreateRootCertificate( keyPair: keyPair, subject: subjectDn, validity: validity, extensions: extensions ); // 7. Visualizzare informazioni certificato Console.WriteLine("\n=== CERTIFICATO ROOT-CA ==="); Console.WriteLine($"Subject: {rootCert.Subject}"); Console.WriteLine($"Issuer: {rootCert.Issuer}"); Console.WriteLine($"Serial: {rootCert.SerialNumber}"); Console.WriteLine($"Not Before: {rootCert.NotBefore:yyyy-MM-dd HH:mm:ss} UTC"); Console.WriteLine($"Not After: {rootCert.NotAfter:yyyy-MM-dd HH:mm:ss} UTC"); Console.WriteLine($"Algorithm: {rootCert.SignatureAlgorithm}"); Console.WriteLine($"Thumbprint: {rootCert.Thumbprint}"); Console.WriteLine($"Is CA: {rootCert.IsCertificateAuthority}"); Console.WriteLine($"Path Length: {rootCert.PathLengthConstraint}"); // 8. Salvare come file PEM string certPath = "root-ca.crt.pem"; string keyPath = "root-ca.key.pem"; // Certificato (pubblico) File.WriteAllText(certPath, rootCert.ExportToPem()); Console.WriteLine($"\nCertificato salvato: {certPath}"); // Chiave privata (crittografata con Argon2id) File.WriteAllText(keyPath, keyPair.ExportToEncryptedPem( password: keyPassword, kdfAlgorithm: KeyDerivationAlgorithm.Argon2id )); Console.WriteLine($"Chiave privata salvata: {keyPath} (crittografata)"); // 9. Validazione: ricaricare certificato e verificare Console.WriteLine("\n=== VALIDAZIONE ==="); using var loadedCert = context.LoadCertificateFromPem(File.ReadAllText(certPath)); using var loadedKey = context.LoadKeyPairFromEncryptedPem( File.ReadAllText(keyPath), keyPassword ); // Verificare autofirma bool signatureValid = loadedCert.VerifySignature(loadedCert); // autofirmato Console.WriteLine($"Autofirma valida: {signatureValid}"); // Verificare corrispondenza coppia chiavi bool keyMatch = loadedCert.PublicKeyMatches(loadedKey); Console.WriteLine($"Match chiave pubblica: {keyMatch}"); Console.WriteLine("\n✓ Root-CA creata con successo!"); } } }
program CreateRootCA; {$APPTYPE CONSOLE} uses SysUtils, DateUtils, WvdS.PqCrypto.FFI; // Unit FFI con dichiarazioni const KEY_PASSWORD = 'MyStr0ng!RootCA#Password2024'; var res: Integer; keypair: Pointer; dn: Pointer; validity: Pointer; ext: Pointer; cert: Pointer; serial: array[0..19] of Byte; pem_buf: array[0..65535] of AnsiChar; pem_len: NativeUInt; begin WriteLn('=== WvdS Creazione Root-CA ==='); WriteLn; // 1. Inizializzare libreria res := wvds_sec_crypto_x509_init(); if res <> WVDS_OK then begin WriteLn('ERRORE: Init fallito (', res, ')'); Exit; end; try // 2. Generare coppia chiavi ML-DSA-65 WriteLn('Generazione coppia chiavi ML-DSA-65...'); keypair := wvds_sec_crypto_x509_keypair_generate_mldsa(65); if keypair = nil then raise Exception.Create('Generazione KeyPair fallita'); // Autotest res := wvds_sec_crypto_x509_keypair_self_test(keypair); if res <> WVDS_OK then raise Exception.Create('Autotest KeyPair fallito'); WriteLn(' Autotest: OK'); // 3. Creare Distinguished Name WriteLn('Creazione Distinguished Name...'); dn := wvds_sec_crypto_x509_dn_create(); if dn = nil then raise Exception.Create('Creazione DN fallita'); wvds_sec_crypto_x509_dn_add_component(dn, PAnsiChar('2.5.4.3'), PAnsiChar('WvdS Root CA')); // CN wvds_sec_crypto_x509_dn_add_component(dn, PAnsiChar('2.5.4.10'), PAnsiChar('DATECpro GmbH')); // O wvds_sec_crypto_x509_dn_add_component(dn, PAnsiChar('2.5.4.11'), PAnsiChar('PQ-Security')); // OU wvds_sec_crypto_x509_dn_add_component(dn, PAnsiChar('2.5.4.6'), PAnsiChar('DE')); // C // 4. Generare numero seriale (20 Bytes = 160 Bit) WriteLn('Generazione numero seriale...'); res := wvds_sec_crypto_x509_serial_generate(@serial[0], 20); if res <> WVDS_OK then raise Exception.Create('Generazione Serial fallita'); // 5. Validità: 20 anni WriteLn('Impostazione periodo di validità (20 anni)...'); validity := wvds_sec_crypto_x509_validity_create( DateTimeToUnix(Now, False), // not_before: adesso DateTimeToUnix(IncYear(Now, 20), False) // not_after: +20 anni ); if validity = nil then raise Exception.Create('Creazione Validity fallita'); // 6. Creare Extensions WriteLn('Impostazione Extensions...'); ext := wvds_sec_crypto_x509_ext_create(); if ext = nil then raise Exception.Create('Creazione Extension fallita'); // BasicConstraints: CA=true, pathLen=1 res := wvds_sec_crypto_x509_ext_set_basic_constraints(ext, True, 1); if res <> WVDS_OK then raise Exception.Create('BasicConstraints fallito'); // KeyUsage: keyCertSign (Bit 5) + cRLSign (Bit 6) = 0x0006 res := wvds_sec_crypto_x509_ext_set_key_usage(ext, $0006); if res <> WVDS_OK then raise Exception.Create('KeyUsage fallito'); // Subject Key Identifier res := wvds_sec_crypto_x509_ext_set_ski_from_keypair(ext, keypair); if res <> WVDS_OK then raise Exception.Create('SKI fallito'); // 7. Creare certificato Root (autofirmato) WriteLn('Creazione certificato Root autofirmato...'); cert := wvds_sec_crypto_x509_cert_create_root( keypair, // Coppia chiavi dn, // Subject (= Issuer per Root) @serial[0], 20, // Numero seriale validity, // Validità ext // Extensions ); if cert = nil then raise Exception.Create('Creazione certificato fallita'); // 8. Salvare come PEM WriteLn; WriteLn('Salvataggio file...'); // Certificato pem_len := SizeOf(pem_buf); res := wvds_sec_crypto_x509_cert_to_pem(cert, @pem_buf[0], @pem_len); if res <> WVDS_OK then raise Exception.Create('Export certificato fallito'); with TFileStream.Create('root-ca.crt.pem', fmCreate) do try Write(pem_buf[0], pem_len); finally Free; end; WriteLn(' root-ca.crt.pem salvato'); // Chiave privata (crittografata) pem_len := SizeOf(pem_buf); res := wvds_sec_crypto_x509_keypair_to_pem_encrypted( keypair, PAnsiChar(KEY_PASSWORD), WVDS_KDF_ARGON2ID, @pem_buf[0], @pem_len ); if res <> WVDS_OK then raise Exception.Create('Export chiave fallito'); with TFileStream.Create('root-ca.key.pem', fmCreate) do try Write(pem_buf[0], pem_len); finally Free; end; WriteLn(' root-ca.key.pem salvato (crittografato)'); WriteLn; WriteLn('=== Root-CA creata con successo! ==='); finally // 9. Cleanup if cert <> nil then wvds_sec_crypto_x509_free_cert(cert); if keypair <> nil then wvds_sec_crypto_x509_free_keypair(keypair); if dn <> nil then wvds_sec_crypto_x509_free_dn(dn); if validity <> nil then wvds_sec_crypto_x509_free_validity(validity); if ext <> nil then wvds_sec_crypto_x509_free_ext(ext); wvds_sec_crypto_x509_shutdown(); end; end.
| Parametro | Tipo | Descrizione | Valori validi |
|---|---|---|---|
level | u8 | Livello di sicurezza ML-DSA | 44, 65, 87 |
| Livello | Sicurezza NIST | Chiave pubblica | Chiave privata | Firma |
|---|---|---|---|---|
| 44 | Livello 2 (~128-bit) | 1.312 Bytes | 2.560 Bytes | 2.420 Bytes |
| 65 | Livello 3 (~192-bit) | 1.952 Bytes | 4.032 Bytes | 3.293 Bytes |
| 87 | Livello 5 (~256-bit) | 2.592 Bytes | 4.896 Bytes | 4.595 Bytes |
| Parametro | Tipo | Descrizione | Esempio |
|---|---|---|---|
dn | *mut DnHandle | Handle DN | – |
oid | *const c_char | OID come stringa | „2.5.4.3“ |
value | *const c_char | Valore UTF-8 | „WvdS Root CA“ |
| OID | Costante | Descrizione | Valore esempio |
|---|---|---|---|
| 2.5.4.3 | OID_CN | Common Name | WvdS Root CA |
| 2.5.4.10 | OID_O | Organization | DATECpro GmbH |
| 2.5.4.11 | OID_OU | Organizational Unit | PQ-Security |
| 2.5.4.6 | OID_C | Country (2 caratteri) | DE |
| 2.5.4.8 | OID_ST | State/Province | Bayern |
| 2.5.4.7 | OID_L | Locality | München |
| Parametro | Tipo | Descrizione | Valore Root-CA |
|---|---|---|---|
ext | *mut ExtHandle | Handle Extension | – |
ca | bool | È certificato CA | true |
path_len | i32 | Lunghezza max. percorso (-1 = illimitato) | 1 o 2 |
| Flag | Bit | Valore | Descrizione |
|---|---|---|---|
| digitalSignature | 0 | 0x0080 | Firme digitali |
| nonRepudiation | 1 | 0x0040 | Non ripudiabilità |
| keyEncipherment | 2 | 0x0020 | Crittografia chiavi |
| dataEncipherment | 3 | 0x0010 | Crittografia dati |
| keyAgreement | 4 | 0x0008 | Accordo chiavi |
| keyCertSign | 5 | 0x0004 | Firma certificati |
| cRLSign | 6 | 0x0002 | Firma CRL |
| encipherOnly | 7 | 0x0001 | Solo crittografia |
Per Root-CA: flags = 0x0006 (keyCertSign + cRLSign)
| Codice | Costante | Significato |
|---|---|---|
| 0 | WVDS_OK | Successo |
| 1 | WVDS_ERROR_INVALID_PARAMETER | Parametro non valido (es. level diverso da 44/65/87) |
| 2 | WVDS_ERROR_OUT_OF_MEMORY | Allocazione memoria fallita |
| 3 | WVDS_ERROR_NOT_INITIALIZED | init() non chiamato |
| 200 | WVDS_ERROR_KEY_GENERATION_FAILED | Generazione chiave fallita |
| 201 | WVDS_ERROR_SIGNATURE_FAILED | Firma fallita |
| 210 | WVDS_ERROR_KEYPAIR_SELF_TEST_FAILED | Autotest fallito |
→ Lista completa: Codici errore
-----BEGIN CERTIFICATE----- MIIHxjCCBiagAwIBAgIUP7J2kM9x... (DER codificato Base64) ... -----END CERTIFICATE-----
| Campo | Valore |
|---|---|
| Version | 3 (0x02) |
| Serial | 20 Bytes casuali |
| Signature Algorithm | ML-DSA-65 (OID: 2.16.840.1.101.3.4.3.18) |
| Issuer | CN=WvdS Root CA, O=DATECpro GmbH, C=DE |
| Subject | CN=WvdS Root CA, O=DATECpro GmbH, C=DE |
| Validity | 20 anni |
| Public Key | ML-DSA-65 (~1.952 Bytes) |
| Extensions | BasicConstraints, KeyUsage, SKI |
| Signature | ML-DSA-65 (~3.293 Bytes) |
-----BEGIN ENCRYPTED PRIVATE KEY----- MIIHbTBXBgkqhkiG9w0BBQ0w... (PKCS#8 EncryptedPrivateKeyInfo) ... -----END ENCRYPTED PRIVATE KEY-----
| Campo | Valore |
|---|---|
| Formato | PKCS#8 EncryptedPrivateKeyInfo |
| KDF | Argon2id (64MB, 3 iterazioni, 4 Lanes) |
| Cipher | AES-256-GCM |
| Key Size | ~4.032 Bytes (chiave privata ML-DSA-65) |
CRITICO - Chiave privata Root-CA:
La chiave privata della Root-CA è l'elemento più critico per la sicurezza dell'intera PKI. La compromissione significa perdita completa della fiducia!
Misure di protezione raccomandate:
Best Practices:
| Problema | Causa | Soluzione |
|---|---|---|
KEY_GENERATION_FAILED | Entropia insufficiente | Verificare sorgente casuale OS, /dev/urandom disponibile? |
KEYPAIR_SELF_TEST_FAILED | Implementazione difettosa | Verificare versione libreria, ricompilare |
| Certificato non valido | DN vuoto | Impostare almeno CN |
| Chiave non leggibile | Password errata | Verificare password, encoding (UTF-8) |
| Errore pathLength | Valore < -1 | -1 per illimitato, 0, 1, 2, … per limite |
NOT_INITIALIZED | init() dimenticato | Chiamare prima wvds_sec_crypto_x509_init() |
| Memory leak | Handle non rilasciati | Chiamare tutte le funzioni free_*() |
| PEM troppo grande | Buffer troppo piccolo | Richiedere dimensione prima (out_len = 0) |
| Relazione | Scenario | Descrizione |
|---|---|---|
| Passo successivo | 1.2 Intermediate-CA | Firmare CA subordinata da Root |
| Poi | 1.4 Trust Store | Distribuire certificato Root |
| Poi | 1.6 CRL/OCSP | Configurare servizi di revoca |
| Alternativa | 11.1 Generare chiavi | Solo chiavi, nessun certificato |
| Correlato | 11.2 Archiviare chiavi | Ulteriori opzioni di archiviazione |
« ← Infrastruttura PKI | ▲ Scenari | 1.2 Intermediate-CA → »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional