3. Controfirme Versione 2
Una controfirma è normalmente definita come una seconda firma che conferma una firma primaria. Un normale esempio di controfirma è la firma che un notaio appone su un documento per testimoniare che hai firmato il documento. Un notaio in genere include un timestamp per indicare quando avviene l'autenticazione; tuttavia, tale timestamp non è stato ancora definito per COSE. Un timestamp, una volta definito in un documento futuro, potrebbe essere incluso come parametro di intestazione protetto. Pertanto, l'applicazione di una controfirma agli oggetti COSE_Signature o COSE_Sign1 corrisponde a questa definizione tradizionale. Questo documento estende il contesto di una controfirma per consentirne l'applicazione a tutte le strutture di sicurezza definite. La controfirma deve essere trattata come un'operazione separata dall'operazione iniziale anche se applicata dallo stesso utente, come avviene in [GROUP-OSCORE].
COSE supporta due diverse forme per le controfirme. Le controfirme complete utilizzano la struttura COSE_Countersignature, che ha la stessa struttura di COSE_Signature. Pertanto, le controfirme complete possono avere attributi protetti e non protetti, incluse le controfirme concatenate. Le controfirme abbreviate utilizzano la struttura COSE_Countersignature0. Questa struttura contiene solo il valore della firma e nient'altro. Le strutture non possono essere convertite tra loro; poiché il calcolo della firma include un parametro che identifica quale struttura viene utilizzata, la struttura convertita fallirà la convalida della firma.
La controfirma versione 2 modifica l'algoritmo utilizzato per calcolare la firma rispetto alla versione originale specificata nella Sezione 4.5 della [RFC8152]. La nuova versione ora include il materiale crittografico generato per tutte le strutture anziché solo per un sottoinsieme.
COSE è stato progettato per uniformità nel modo in cui sono specificate le strutture dati. Uno dei risultati è che per COSE si può espandere il concetto di controfirme oltre la semplice idea di firmare una firma per poter firmare la maggior parte delle strutture senza dover creare un nuovo livello di firma. Quando si crea una controfirma, è necessario avere chiaro quali proprietà di sicurezza ne risultano. Se eseguita su un COSE_Signature o COSE_Sign1, la normale semantica della controfirma viene preservata. Cioè, la controfirma fa una dichiarazione sull'esistenza di una firma e, se utilizzata con un timestamp ancora da specificare, un momento in cui la firma esiste. Se eseguita su un COSE_Mac o COSE_Mac0, il payload è incluso così come il valore MAC. Se eseguita su un COSE_Encrypt o COSE_Encrypt0, viene attestata l'esistenza dei dati crittografati. Va notato che c'è una distinzione tra attestare i dati crittografati rispetto all'attestare i dati non crittografati. Se quest'ultimo è ciò che si desidera, allora è necessario applicare una firma ai dati e quindi crittografarli. È sempre possibile costruire casi in cui l'uso di due chiavi diverse si traduce in una decrittografia di successo, in cui il controllo del tag ha esito positivo, ma vengono prodotti due testi in chiaro completamente diversi. Questa situazione non è rilevabile da una controfirma sui dati crittografati.
3.1. Controfirme complete
La struttura COSE_Countersignature consente lo stesso set di funzionalità di un COSE_Signature. Ciò significa che tutte le funzionalità di una firma sono duplicate con questa struttura. Nello specifico, il controfirmatario non deve essere correlato al produttore di ciò che viene controfirmato, poiché l'identificazione della chiave e dell'algoritmo può essere inserita negli attributi della controfirma. Ciò significa anche che la controfirma stessa può essere controfirmata. Questa è una funzionalità richiesta da protocolli come i servizi di archiviazione a lungo termine. Maggiori informazioni su come vengono utilizzate le controfirme possono essere trovate nella sintassi del record delle prove descritta nella [RFC4998].
La struttura completa della controfirma può essere codificata come taggata o non taggata, a seconda del contesto. Una struttura COSE_Countersignature taggata è identificata dal tag CBOR 19. La struttura della controfirma è la stessa utilizzata per un firmatario su un oggetto firmato. Il frammento CDDL per le controfirme complete è:
COSE_Countersignature_Tagged = #6.19(COSE_Countersignature)
COSE_Countersignature = COSE_Signature
I dettagli dei campi di una controfirma si trovano nella Sezione 4.1 della [RFC9052].
Un esempio di controfirma su una firma si trova nell'Appendice A.1.1. Un esempio di controfirma in un oggetto di crittografia si trova nell'Appendice A.3.1.
Va notato che solo un algoritmo di firma con appendice (vedere la Sezione 8.1 della [RFC9052]) può essere utilizzato per le controfirme. Questo perché il corpo dovrebbe poter essere elaborato senza dover valutare la controfirma, e questo non è possibile per gli schemi di firma con recupero del messaggio.
3.2. Controfirme abbreviate
Le controfirme abbreviate supportano la messaggistica di gruppo crittografata in cui è richiesta l'identificazione dell'autore del messaggio ma si desidera mantenere la controfirma il più piccola possibile. Per le controfirme abbreviate, non è prevista alcuna disposizione per attributi protetti relativi all'operazione di firma. Cioè, i parametri per il calcolo o la verifica della controfirma abbreviata sono forniti dallo stesso contesto utilizzato per descrivere la crittografia, la firma o l'elaborazione MAC.
Il frammento CDDL per le controfirme abbreviate è:
COSE_Countersignature0 = bstr
La stringa di byte che rappresenta il valore della firma viene inserita nell'attributo Countersignature0. Questo attributo viene quindi codificato come parametro di intestazione non protetto.
3.3. Processo di firma e verifica
Per creare una firma, è necessaria una stringa di byte ben definita. La Countersign_structure viene utilizzata per creare la forma canonica. Questo processo di firma e verifica accetta la struttura di destinazione della controfirma (COSE_Signature, COSE_Sign1, COSE_Sign, COSE_Mac, COSE_Mac0, COSE_Encrypt o COSE_Encrypt0), le informazioni sul firmatario (COSE_Signature) e i dati dell'applicazione (fonte esterna). Una Countersign_structure è un array CBOR. La struttura di destinazione della controfirma deve avere tutte le sue funzioni crittografiche finalizzate prima di calcolare la firma. I campi della Countersign_structure, in ordine, sono:
context: Una stringa di testo di contesto che identifica il contesto della firma. La stringa di testo di contesto è una delle seguenti:
-
"CounterSignature" per controfirme che utilizzano la struttura COSE_Countersignature quando other_fields è assente.
-
"CounterSignature0" per controfirme che utilizzano la struttura COSE_Countersignature0 quando other_fields è assente.
-
"CounterSignatureV2" per controfirme che utilizzano la struttura COSE_Countersignature quando other_fields è presente.
-
"CounterSignature0V2" per controfirme che utilizzano la struttura COSE_Countersignature0 quando other_fields è presente.
body_protected: Gli attributi protetti serializzati dalla struttura di destinazione, codificati in un tipo bstr. Se non ci sono attributi protetti, viene utilizzata una stringa di byte di lunghezza zero.
sign_protected: Gli attributi protetti serializzati dalla struttura del firmatario, codificati in un tipo bstr. Se non ci sono attributi protetti, viene utilizzata una stringa di byte di lunghezza zero. Questo campo viene omesso per l'attributo Countersignature0V2.
external_aad: I dati autenticati aggiuntivi (AAD) forniti esternamente dall'applicazione, codificati in un tipo bstr. Se questo campo non viene fornito, il valore predefinito è una stringa di byte di lunghezza zero. (Vedere la Sezione 4.4 della [RFC9052] per la guida all'applicazione sulla costruzione di questo campo.)
payload: Il payload da firmare, codificato in un tipo bstr. Il payload viene inserito qui indipendentemente da come viene trasportato.
other_fields: Omesso se ci sono solo due campi bstr nella struttura di destinazione. Questo campo è un array di tutti i campi bstr dopo il secondo. Ad esempio, questo sarebbe un array di un elemento per la struttura COSE_Sign1 contenente il valore della firma.
Il frammento CDDL che descrive il testo sopra è:
Countersign_structure = [
context : "CounterSignature" / "CounterSignature0" /
"CounterSignatureV2" / "CounterSignature0V2" /,
body_protected : empty_or_serialized_map,
? sign_protected : empty_or_serialized_map,
external_aad : bstr,
payload : bstr,
? other_fields : [+ bstr ]
]
Come calcolare una controfirma:
-
Creare una Countersign_structure e compilarla con i campi appropriati.
-
Creare il valore ToBeSigned codificando la Countersign_structure in una stringa di byte, utilizzando la codifica descritta nella Sezione 4.
-
Chiamare l'algoritmo di creazione della firma passando K (la chiave con cui firmare), alg (l'algoritmo con cui firmare) e ToBeSigned (il valore da firmare).
-
Posizionare il valore della firma risultante nella posizione corretta. Questo è il campo "signature" della struttura COSE_Countersignature per le controfirme complete (vedere la Sezione 3.1). Questo è il valore dell'attributo Countersignature0 per le controfirme abbreviate (vedere la Sezione 3.2).
I passaggi per verificare una controfirma:
-
Creare una Countersign_structure e compilarla con i campi appropriati.
-
Creare il valore ToBeSigned codificando la Countersign_structure in una stringa di byte, utilizzando la codifica descritta nella Sezione 4.
-
Chiamare l'algoritmo di verifica della firma passando K (la chiave con cui verificare), alg (l'algoritmo utilizzato per firmare), ToBeSigned (il valore da firmare) e sig (la firma da verificare).
Oltre a eseguire la verifica della firma, l'applicazione esegue i controlli appropriati per garantire che la chiave sia correttamente associata all'identità di firma e che l'identità di firma sia autorizzata prima di eseguire azioni.