# Protocollo TCN ## Descrizione del protocollo ### Chiavi di autenticazione e verifica ### Chiave temporanea di contatto {#sec:tck} ### Numeri temporanei di contatto ### Report ## Implementazione del protocollo per la JMV Al fine di utilizzare il protocollo precedentemente descritto all'interno dell'applicazione Android, ne è stato sviluppato un'implementazione per la *Java Virtual Machine*. La gestione della coppia di chiavi derivate dalla curva ellittica *Ed25519* è stata affidata alla libreria ***ed25519-elisabeth*** @CryptographycafeEd25519elisabeth2020. Le chiavi private e pubbliche prodotte sono state *wrappate* rispettivamente nelle classi `ReportAuthorizationKey` e `ReportVerificationKey`. Questa scelta non solo ha permesso di utilizzare nomi dal maggiore significato rispetto al dominio applicativo, ma anche di nascondere l'implementazione della curva *Ed25519* in modo da disaccoppiare l'interfaccia della libreria crittografica da quella utilizzata per il protocollo TCN. Come illustrato nella @sec:tck, a partire dalla chiave di autorizzazione è possibile ricavare la `TemporaryContactKey` iniziale[^tck-0]. Ciò può essere fatto traverso la funzione `baseTemporaryContactKey()`, la cui implementazione è riportata nel @lst:tck-0. Invece, partendo da una chiave di contatto generica, è possibile ricavare la successiva chiave di contatto attraverso il metodo `nextTemporaryContactKey()` riportato nel listato @lst:next-tck. [^tck-0]: La chiave temporanea iniziale viene ricavata a partire dalla sola *rak* e da essa non è generato nessun numero temporaneo di contatto. ``` {.kotlin #lst:tck-0 caption="Derivazione della prima tck."} fun baseTemporaryContactKey(): TemporaryContactKey { val hmac = MessageDigest.getInstance("SHA-256").apply { update(Const.H_TCK_DOMAIN_SEPARATOR) update(key.toByteArray()) } return TemporaryContactKey.createFromByteArray( hmac.digest(), 0 ) } ``` ``` {.kotlin #lst:next-tck caption="Generazione della prossima tck."} fun nextTemporaryContactKey( rvk: ReportVerificationKey ): TemporaryContactKey { val hmac = MessageDigest.getInstance("SHA-256").apply { update(Const.H_TCK_DOMAIN_SEPARATOR) update(rvk.toByteArray()) update(key) } return TemporaryContactKey( hmac.digest(), index.inc() ) } ``` Sempre a partire dalla tck è possibile ricavare il numero di contatto temporaneo (tcn) e da esso l'UUID utilizzato all'interno dei beacon bluetooth. Questa operazione può essere eseguita mediante la funzione `deriveTemporaryContactNumber()` la cui implementazione è stata riportata nel @lst:derive-tcn. ``` {.kotlin #lst:derive-tcn caption="Derivazione del numero di contatto temporaneo."} fun deriveTemporaryContactNumber(): TemporaryContactNumber { val hmac = MessageDigest.getInstance("SHA-256").apply { update(Const.H_TCN_DOMAIN_SEPARATOR) update(index.toLeByteArray()) update(key) } return TemporaryContactNumber( hmac.digest().sliceArray(0 until 16), index ) } ``` Un'altra componente fondamentale dell'implementazione del protocollo TCN è la classe `Report`, infatti tramite essa è possibile generare il report firmato che poi sarà inviato al server. Inoltre questa classe mette a disposizione una serie di funzioni di utilità come `generateContactNumbers()` e `toReportData()` che facilitano l'estrazione delle informazioni contenute all'interno del report. Infine la classe report fornisce anche un metodo statico, `readReportDataFromByteArray()`, attraverso il quale altre componenti applicative sono in grado di recuperare le informazioni di un report contenute all'interno di un array di bytes. L'implementazione di questo metodo è riportata nel listato @lst:read-report. ``` {.kotlin #lst:read-report caption="Lettura dei dati di un report da un ByteArray."} fun readReportDataFromByteArray(bytes: ByteArray): ReportData { val buffer = ByteBuffer.wrap(bytes).apply { order(ByteOrder.LITTLE_ENDIAN) } val rvk = ReportVerificationKey .createFromByteArray(buffer.read(32)) val tckBytes = buffer.read(32) val from = buffer.short val until = buffer.short val memoType = buffer.get() val memoData = String(buffer.read(buffer.get().toInt())) return ReportData( rvk, TemporaryContactKey .createFromByteArray(tckBytes, from.dec()), from, until, memoData ) } ``` # Applicazione ## Bluetooth ### Trasmissione ### Scansione ### Stima della distanza ## UI ## Memorizzazione ## Rete