
Libreria per SRTP (Secure Realtime Transport Protocol)
Questo pacchetto fornisce un'implementazione del Secure Real-time Transport Protocol (SRTP), della Universal Security Transform (UST) e di un kernel crittografico di supporto. L'API SRTP è documentata in include/srtp.h, e la libreria si trova in libsrtp2.a (dopo la compilazione).
Questo documento descrive libSRTP, la libreria Secure RTP open source di Cisco Systems, Inc. RTP è il Real-time Transport Protocol, uno standard IETF per il trasporto di dati in tempo reale come telefonia, audio e video, definito dalla RFC 3550. Secure RTP (SRTP) è un profilo RTP che fornisce riservatezza ai dati RTP e autenticazione all'intestazione e al payload RTP. SRTP è uno standard IETF, definito nella RFC 3711, ed è stato sviluppato nel gruppo di lavoro IETF Audio/Video Transport (AVT). Questa libreria supporta tutte le funzionalità obbligatorie di SRTP, ma non tutte quelle opzionali. Vedere la sezione Funzionalità supportate per informazioni più dettagliate.
Questo documento viene inoltre utilizzato per generare i file di documentazione nella cartella /doc/ dove può essere creata una referenza più dettagliata all'API libSRTP e alle funzioni correlate (richiede l'installazione di doxygen). Il materiale di riferimento viene creato automaticamente dai commenti incorporati in alcuni file header C. La documentazione è organizzata in moduli per migliorarne la chiarezza. Questi moduli non corrispondono direttamente ai file. Un kernel crittografico sottostante fornisce gran parte della funzionalità di base di libSRTP ma è in gran parte non documentato perché svolge il suo lavoro dietro le quinte.
[email protected] lista di discussione generale per notizie / annunci / discussioni. Questa è una lista aperta, vedere https://lists.packetizer.com/mailman/listinfo/libsrtp per iscriversi.
[email protected] per segnalare problemi di sicurezza al team di manutenzione di libsrtp. Questa è una lista chiusa, ma chiunque può inviarvi messaggi.
libSRTP è distribuito sotto la seguente licenza, inclusa nella distribuzione del codice sorgente. È riprodotta nel manuale nel caso in cui abbiate ottenuto la libreria da un'altra fonte.
Copyright (c) 2001-2017 Cisco Systems, Inc. Tutti i diritti riservati.
La ridistribuzione e l'uso in forma sorgente e binaria, con o senza modifiche, sono consentiti purché siano soddisfatte le seguenti condizioni:
- Le ridistribuzioni del codice sorgente devono conservare il suddetto avviso di copyright questo elenco di condizioni e la seguente dichiarazione di non responsabilità.
- Le ridistribuzioni in forma binaria devono riprodurre il suddetto avviso di copyright questo elenco di condizioni e la seguente dichiarazione di non responsabilità in la documentazione e/o altri materiali forniti con la distribuzione.
- Né il nome di Cisco Systems, Inc. né i nomi dei suoi contributori possono essere utilizzati per approvare o promuovere prodotti derivati da questo software senza una preventiva autorizzazione scritta specifica.
QUESTO SOFTWARE È FORNITO DAI DETENTORI DEL COPYRIGHT E DAI CONTRIBUTORI "COSÌ COM'È" E QUALSIASI GARANZIA ESPRESSA O IMPLICITA, INCLUSI, MA NON LIMITATI A, LE GARANZIE IMPLICITE DI COMMERCIABILITÀ E IDONEITÀ PER UNO SCOPO PARTICOLARE, SONO DECLINATE. IN NESSUN CASO I DETENTORI DEL COPYRIGHT O I CONTRIBUTORI SARANNO RESPONSABILI PER DANNI DIRETTI, INDIRETTI, INCIDENTALI, SPECIALI, ESEMPLARI O CONSEQUENZIALI (INCLUSI, MA NON LIMITATI A, L'APPROVVIGIONAMENTO DI BENI O SERVIZI SOSTITUTIVI; LA PERDITA DI UTILIZZO, DATI O PROFITTI; O L'INTERRUZIONE DELL'ATTIVITÀ) COMUNQUE CAUSATI E SU QUALSIASI TEORIA DI RESPONSABILITÀ, SIA CONTRATTUALE, RESPONSABILITÀ OGGETTIVA O ILLECITO (INCLUSI NEGLIGENZA O ALTRO) DERIVANTI IN QUALSIASI MODO DALL'USO DI QUESTO SOFTWARE, ANCHE SE AVVISATI DELLA POSSIBILITÀ DI TALI DANNI.
libSRTP fornisce funzioni per proteggere RTP e RTCP. I pacchetti RTP
possono essere crittografati e autenticati (usando la funzione srtp_protect()),
trasformandoli in pacchetti SRTP. Analogamente, i pacchetti SRTP
possono essere decrittografati e la loro autenticazione verificata (usando la
funzione srtp_unprotect()), trasformandoli in pacchetti RTP. Funzioni simili
applicano la sicurezza ai pacchetti RTCP.
Il typedef srtp_stream_t punta a una struttura che contiene tutto lo
stato associato a un flusso SRTP, incluse le chiavi e i parametri per le
funzioni di cifratura e autenticazione dei messaggi e i dati anti-replay. Una
particolare srtp_stream_t contiene le informazioni necessarie per proteggere un
particolare flusso RTP e RTCP. Questo tipo di dato è intenzionalmente opaco
per separare meglio l'API libSRTP dalla sua implementazione.
All'interno di una sessione SRTP, possono esserci più flussi, ciascuno
originato da un particolare mittente. Ogni sorgente utilizza un contesto di flusso
distinto per proteggere il flusso RTP e RTCP che sta originando. Il typedef srtp_t
punta a una struttura che contiene tutto lo stato associato a una sessione SRTP.
Possono esserci più contesti di flusso associati a un singolo srtp_t. Un contesto di flusso
non può esistere indipendentemente da un srtp_t, anche se ovviamente può essere creato
un srtp_t che contiene un solo contesto di flusso. Un dispositivo che partecipa
a una sessione SRTP deve avere un contesto di flusso per ogni sorgente nella sessione,
così da poter elaborare i dati che riceve da ciascun mittente.
In libSRTP, una sessione viene creata utilizzando la funzione srtp_create().
La policy da implementare nella sessione viene passata a questa
funzione come handle opaco srtp_policy_t. Un singolo handle di policy
descrive una policy di flusso. Per configurare più flussi, creare una
sessione e aggiungere ulteriori policy con srtp_stream_add().
Un handle di policy viene configurato con le funzioni srtp_policy_set_*. Come minimo,
ciò include la selezione SSRC, la selezione del profilo e il materiale chiave/sale.
Il profilo configura le impostazioni della policy crittografica RTP/RTCP, mentre il
selettore SSRC identifica come e dove viene applicata tale policy.
In questa sezione esaminiamo SRTP e introduciamo alcuni termini utilizzati in libSRTP. Una sessione RTP è definita da una coppia di indirizzi di trasporto di destinazione, ovvero un indirizzo di rete più una coppia di porte UDP per RTP e RTCP. RTCP, il protocollo di controllo RTP, viene utilizzato per coordinare i partecipanti di una sessione RTP, ad esempio per fornire feedback dai ricevitori ai mittenti. Una sessione SRTP è definita in modo analogo; è semplicemente una sessione RTP per la quale viene utilizzato il profilo SRTP. Una sessione SRTP è costituita dal traffico inviato agli indirizzi di trasporto di destinazione SRTP o SRTCP. Ogni partecipante a una sessione è identificato da un identificatore di sincronizzazione della sorgente (SSRC). Alcuni partecipanti potrebbero non inviare traffico SRTP; vengono chiamati ricevitori, anche se inviano traffico SRTCP, come i report dei ricevitori.
RTP consente a più sorgenti di inviare traffico RTP e RTCP durante la stessa sessione. L'identificatore di sincronizzazione della sorgente (SSRC) viene utilizzato per distinguere queste sorgenti. In libSRTP, chiamiamo flusso il traffico SRTP e SRTCP proveniente da una particolare sorgente. Ogni flusso ha il proprio SSRC, numero di sequenza, contatore di rollover e altri dati. Una particolare scelta di opzioni, meccanismi crittografici e chiavi viene chiamata policy. Ogni flusso all'interno di una sessione può avere una policy distinta applicata.
Una singola policy può essere utilizzata per tutti i flussi in una data sessione, anche se il caso in cui una singola chiave viene condivisa tra più flussi richiede attenzione. Quando si utilizza la condivisione delle chiavi, i valori SSRC che identificano i flussi devono essere distinti. Questo requisito può essere applicato utilizzando la convenzione per cui ogni chiave SRTP e SRTCP viene utilizzata per la cifratura da un solo mittente. In altre parole, la chiave è condivisa solo tra i flussi che originano da un particolare dispositivo (ovviamente, altri partecipanti SRTP dovranno utilizzare la chiave per la decifratura). libSRTP supporta questa applicazione rilevando il caso in cui una chiave viene utilizzata sia per i dati in ingresso che per quelli in uscita.
Questa libreria supporta tutte le funzionalità obbligatorie da implementare di
SRTP (come definite nella RFC 3711). Alcune di queste
funzionalità possono essere selezionate (o deselezionate) in fase di esecuzione impostando
una policy appropriata tramite un handle srtp_policy_t.
Alcuni altri comportamenti del protocollo possono essere adattati definendo un
gestore di eventi appropriato per gli eventi eccezionali; vedere la sezione SRTPevents
nella documentazione generata.
Alcune opzioni descritte nella specifica SRTP non sono supportate. Questo include
L'utente deve essere consapevole che è possibile fare un uso improprio di questa libreria, e che il risultato potrebbe essere un livello di sicurezza inadeguato. Se si implementa una funzionalità utilizzando questa libreria, si vorrà leggere la sezione Security Considerations della RFC 3711. Inoltre, è importante leggere e comprendere i termini delineati nella sezione Licenza e dichiarazione di non responsabilità.
Questa libreria supporta anche i metodi di cifratura autenticata AES-GCM descritti nella RFC 7714
È possibile configurare il backend crittografico di terze parti (es. openssl/nss/etc) con cui verrà compilato libSRTP. Se non viene impostato alcun backend di terze parti, libSRTP fornisce un'implementazione interna di AES e Sha1. L'implementazione interna supporta solo AES-128 e AES-256, quindi per utilizzare AES-192 o il gruppo di cifrature AES-GCM è necessario configurare un backend crittografico di terze parti. Per questo motivo e per ragioni di prestazioni, è altamente consigliato utilizzare un backend crittografico di terze parti.
La funzione srtp_protect() presuppone che il buffer che contiene il
pacchetto rtp disponga di spazio di archiviazione sufficiente affinché il tag
di autenticazione possa essere scritto alla fine del pacchetto. Se questa ipotesi
non è valida, ne conseguirà una corruzione della memoria.
I test automatici per le funzioni crittografiche sono forniti tramite
le funzioni cipher_type_self_test() e auth_type_self_test().
Queste funzioni dovrebbero essere utilizzate per testare ogni porting di questo codice
su una nuova piattaforma.
La protezione anti-replay è contenuta nel motore crittografico e ne vengono forniti i test.
Questa implementazione fornisce chiamate per inizializzare, proteggere e rimuovere la protezione dei pacchetti RTP e fa il minor numero possibile di assunzioni su come queste funzioni verranno chiamate. Ad esempio, non è previsto che il chiamante fornisca i pacchetti in ordine (anche se se vengono chiamate fuori sequenza per più di 65k, la sincronizzazione andrà persa).
Il numero di sequenza nel pacchetto rtp viene utilizzato come 16 bit inferiori
dell'indice locale del pacchetto del mittente. Notare che RTP farà iniziare il suo
numero di sequenza in una posizione casuale e il livello SRTP salta semplicemente
avanti a quel numero alla sua prima invocazione. Una versione precedente
di questa libreria utilizzava numeri di sequenza iniziali inferiori
a 32.768; questo trucco non è più necessario poiché la funzione
rdbx_estimate_index(...) è stata resa più intelligente a partire dalla
versione 1.0.1.
La finestra anti-replay per (S)RTCP è impostata staticamente a 128 bit di lunghezza.
Per installare libSRTP, scaricare l'ultima release della distribuzione
da https://github.com/cisco/libsrtp/releases.
Probabilmente si desidera ottenere la release più recente. Decomprimere la distribuzione ed
estrarre i file sorgente; la directory in cui verranno inseriti i file sorgente
si chiama libsrtp-A-B-C, dove A è il numero di versione, B è il numero di
release principale e C è il numero di release minore.
libSRTP utilizza le utility GNU autoconf e make (BSD make non funzionerà; se
entrambe le versioni di make sono presenti sulla piattaforma, è possibile invocare GNU make come
gmake.). Nella directory libsrtp, eseguire lo script configure e poi
make:~~~.txt
./configure [ options ]
make
Lo script configure accetta le seguenti opzioni:
Option | Description
-------------------------------|--------------------
\-\-help \-h | Mostra l'aiuto
\-\-enable-debug-logging | Abilita il logging di debug in tutti i moduli
\-\-enable-openssl | Abilita il motore crittografico OpenSSL
\-\-enable-nss | Abilita il motore crittografico NSS
\-\-enable-openssl-kdf | Abilita l'algoritmo KDF di OpenSSL
\-\-enable-log-stdout | Abilita il logging su stdout
\-\-with-openssl-dir | Posizione dell'installazione di OpenSSL
\-\-with-nss-dir | Posizione dell'installazione di NSS
\-\-with-log-file | Usa un file per il logging
Per impostazione predefinita non viene prodotto alcun log; il logging può essere abilitato per essere inviato su stdout
o su un determinato file utilizzando le opzioni di configure.
Questo pacchetto è stato testato sulle seguenti piattaforme: Mac OS X
(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris
(sparc-sun-solaris2.6), RedHat Linux 7.1 e 9 (i686-pc-linux), e
OpenBSD (sparc-unknown-openbsd2.7).
--------------------------------------------------------------------------------
<a name="changing-build-configuration"></a>
## Modifica della Configurazione di Build
Per generare lo script `./configure` menzionato sopra, libSRTP si basa sul toolchain [automake](https://www.gnu.org/software/automake/). Poiché `./configure` è generato da `configure.in` tramite automake, se si apportano modifiche al funzionamento di `./configure` (ad esempio, per aggiungere una nuova dipendenza da una libreria), sarà necessario rigenerare `./configure` e committare la versione aggiornata. In aggiunta ad automake stesso, dovrai avere installati anche gli strumenti `pkgconfig`.
Per esempio, su macOS:```
brew install automake pkgconfig
# Edit configure.in
autoremake -ivf
```
<a name="using-visual-studio"></a>
## Utilizzo di Visual Studio
Su Windows è possibile utilizzare Visual Studio tramite CMake. CMake può essere scaricato qui:
https://cmake.org/ . Per creare i file di build di Visual Studio, ad esempio eseguire i
seguenti comandi:```
# Create build subdirectory
mkdir build
cd build
# Make project files
cmake .. -G "Visual Studio 15 2017"
# Or for 64 bit project files
cmake .. -G "Visual Studio 15 2017 Win64"
```
<a name="using-meson"></a>
## Uso di Meson
Su tutte le piattaforme, incluso Windows, è possibile compilare usando [Meson](https://mesonbuild.com).
I passaggi per scaricare Meson sono qui: https://mesonbuild.com/Getting-meson.html
Per compilare con Meson, puoi fare qualcosa come:```
# Setup the build subdirectory
meson setup --prefix=/path/to/prefix builddir
# Build the project
meson compile -C builddir
# Run tests
meson test -C builddir
# Optionally, install
meson install -C builddir
```
Per compilare con Visual Studio, esegui i comandi precedenti da un prompt dei comandi di Visual Studio, oppure esegui `vcvarsall.bat` con gli argomenti appropriati all'interno di un Prompt dei comandi.
Nota che puoi anche sostituire i comandi precedenti con i target `ninja` appropriati: `ninja -C build`, `ninja -C build test`, `ninja -C build install`.
--------------------------------------------------------------------------------
<a name="applications"></a>
# Applicazioni
Diversi driver di test e una semplice applicazione srtp portabile sono inclusi nella sottodirectory `test/`.
Driver di test | Funzione testata
--------- | -------
kernel_driver | kernel crittografico (cifrari, funzioni di autenticazione, rng)
srtp_driver | test srtp in memoria (non usa la rete)
rdbx_driver | rdbx (database di replay esteso)
roc_driver | funzioni dei numeri di sequenza estesi
replay_driver | database di replay
cipher_driver | cifrari
auth_driver | funzioni di hash
L'app `rtpw` è una semplice applicazione rtp che legge le parole da `/usr/dict/words` e poi le invia una alla volta usando [s]rtp. L'impostazione manuale della chiave srtp utilizza l'opzione -k; la gestione automatica delle chiavi tramite gdoi verrà aggiunta in seguito.
utilizzo:~~~.txt
rtpw [[-d <debug>]* [-k|b <key> [-a][-e <key size>][-g]] [-s | -r] dest_ip dest_port] | [-l]
È necessario scegliere l'opzione -s (mittente) o -r (ricevitore). I
valori dest_ip, dest_port sono l'indirizzo IP e la porta UDP a cui
verrà inviato il dizionario, rispettivamente.
Le opzioni sono:
Per ottenere valori casuali da 30 byte da usare come coppie chiave/sale, puoi
usare la seguente funzione bash per formattare l'output di
/dev/random (dove tale dispositivo è disponibile).~~~.txt
function randhex() {
cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }'
}
Un esempio di sessione SRTP che utilizza due programmi rtpw è il seguente:~~~.txt
set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh1]$ test/rtpw -s -k $k -e 128 -a 0.0.0.0 9999
Security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
setting SSRC to 2078917053
sending word: A
sending word: a
sending word: aa
sending word: aal
...
[sh2]$ test/rtpw -r -k $k -e 128 -a 0.0.0.0 9999
security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
19 octets received from SSRC 2078917053 word: A
19 octets received from SSRC 2078917053 word: a
20 octets received from SSRC 2078917053 word: aa
21 octets received from SSRC 2078917053 word: aal
...
Questa sezione fornisce un semplice esempio di come utilizzare libSRTP. Qui assumiamo
che le funzioni get_rtp_packet() e send_srtp_packet() siano disponibili
per noi. La prima inserisce un pacchetto RTP
nel buffer e restituisce il numero di ottetti scritti in quel
buffer. La seconda invia il pacchetto RTP nel buffer, data la
lunghezza come suo secondo argomento.~~~.c
srtp_t session;
srtp_policy_t policy;
// Set key/salt to predetermined values. uint8_t master_key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; uint8_t master_salt[14] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D};
// Initialize libSRTP. srtp_init();
// Create and configure an opaque policy handle. srtp_policy_create(&policy); srtp_policy_set_ssrc(policy, (srtp_ssrc_t){ssrc_any_outbound, 0}); srtp_policy_set_profile(policy, srtp_profile_aes128_cm_sha1_80); srtp_policy_add_key(policy, master_key, sizeof(master_key), master_salt, sizeof(master_salt), NULL, 0);
// Allocate and initialize the SRTP session. srtp_create(&session, policy);
srtp_policy_destroy(policy);
// Main loop: get RTP packets, send SRTP packets. while (1) { char rtp_buffer[2048]; size_t rtp_len; char srtp_buffer[2048]; size_t srtp_len = sizeof(srtp_buffer);
rtp_len = get_rtp_packet(rtp_buffer); srtp_protect(session, rtp_buffer, rtp_len, srtp_buffer, &srtp_len); send_srtp_packet(srtp_buffer, srtp_len); }
srtp_dealloc(session); srtp_shutdown();
<a name="credits"></a>
# Crediti
L'implementazione originale e la documentazione di libSRTP sono state scritte
da David McGrew di Cisco Systems, Inc. per promuovere l'uso,
la comprensione e l'interoperabilità di Secure RTP. Michael Jerris
ha contribuito con il supporto per la compilazione con MSVC. Andris Pavenis
ha contribuito con molte correzioni importanti. Brian West ha contribuito con modifiche per
abilitare il linking dinamico. Yves Shumann ha segnalato bug nella documentazione.
Randell Jesup ha contribuito con un'implementazione funzionante di SRTCP e altre
correzioni. Steve Underwood ha contribuito con modifiche per la portabilità su x86_64. Ringraziamo anche
Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill
Simon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo e
altri per contributi, commenti e correzioni.
Questo materiale di riferimento, ove applicabile, in questa documentazione è stato generato
utilizzando l'utility doxygen per la documentazione automatica del codice sorgente.
Copyright 2001-2005 di David A. McGrew, Cisco Systems, Inc.
--------------------------------------------------------------------------------
<a name="references"></a>
# Riferimenti
Riferimenti SRTP e ICM
Settembre 2005
Secure RTP è definito nella [RFC 3711](https://tools.ietf.org/html/rfc3711).
La definizione della modalità contatore è nella [Sezione 4.1.1](https://tools.ietf.org/html/rfc3711#section-4.1.1).
SHA-1 è definito in [FIPS PUB 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
HMAC è definito nella [RFC 2104](https://tools.ietf.org/html/rfc2104)
e i vettori di test HMAC-SHA1 sono disponibili
nella [RFC 2202](https://tools.ietf.org/html/rfc2202#section-3).
L'uso di AES-GCM in SRTP è definito nella [RFC 7714](https://tools.ietf.org/html/rfc7714).
| Option | Description |
|---|
| -s | mittente (S)RTP - fa sì che l'app invii le parole |
| -r | ricevitore (S)RTP - fa sì che l'app riceva le parole |
| -k | usa la chiave master SRTP , dove la chiave è un esadecimale (senza il prefisso "0x") |
| -b | come -k ma con chiave codificata in base64 |
| -e | crittografa/decrittografa (per la riservatezza dei dati) (richiede anche l'uso dell'opzione -k) (usa 128, 192 o 256 per keysize) |
| -g | usa la modalità AES-GCM (deve essere usata con -e) |
| -a | autenticazione del messaggio (richiede anche l'uso dell'opzione -k) |
| -l | elenca i moduli di debug disponibili |
| -d | attiva il debug per il modulo |