sheave_core

Module handshake

Source
Expand description

§Types for the handshake step in RTMP.

In RTMP, first, both sides are required doing handshake. It is done respectively following steps:

  1. Specifies RTMP version.
  2. Exchanges handshake data each other.
  3. Returns partner’s handshake data.

§RTMP version

1 byte to specify a kind of encryption. Default is 3. This means doing handshake as the Raw RTMP, that is, not to encrypt. Server should respond 3 if encryption specified by client has not implemented. In this case, client can either degrade version to 3 or disconnect with server.

§Handshake

1536 bytes of actual handshake data. Note this can be imprinted HMAC-SHA256 diegst/signature according to version of Flash Player/Flash Media Server. Concretely, it is imprinted when respective version is following:

  • Flash Player: >= 9
  • Flash Media Server: >= 3

§Examples

Both sides are required taking following steps each version.

  • Below Flash Player 9/Flash Media Server 3
use std::time::Duration;
use sheave_core::handshake::{
    Handshake,
    Version
};

let handshake = Handshake::new(Duration::default(), Version::UNSIGNED);
  • And above Flash Player 9/Flash Media Server 3
use std::time::Duration;
use sheave_core::handshake::{
    Handshake,
    Version,
    EncryptionAlgorithm
};

// In a case of exchanging client-side request with server-side response.
let mut client_handshake = Handshake::new(Duration::default(), Version::LATEST_CLIENT);
client_handshake.imprint_digest(EncryptionAlgorithm::NotEncrypted, Handshake::CLIENT_KEY);
let mut key: Vec<u8> = Vec::new();
key.extend_from_slice(Handshake::SERVER_KEY);
key.extend_from_slice(Handshake::COMMON_KEY);
client_handshake.imprint_signature(EncryptionAlgorithm::NotEncrypted, key.as_slice());
assert!(client_handshake.did_signature_match(EncryptionAlgorithm::NotEncrypted, key.as_slice()));

// In a case of exchanging server-side request with client-side response.
let mut server_handshake = Handshake::new(Duration::default(), Version::LATEST_SERVER);
server_handshake.imprint_digest(EncryptionAlgorithm::NotEncrypted, Handshake::SERVER_KEY);
let mut key: Vec<u8> = Vec::new();
key.extend_from_slice(Handshake::CLIENT_KEY);
key.extend_from_slice(Handshake::COMMON_KEY);
server_handshake.imprint_signature(EncryptionAlgorithm::NotEncrypted, key.as_slice());
assert!(server_handshake.did_signature_match(EncryptionAlgorithm::NotEncrypted, key.as_slice()));

§Encryption

Currently, to implement handshake encryption isn’t planned following causes:

  1. Connected socket is in full view from outside. This is insecure though chunk is encrypted.
  2. If chunk encryption is implemented on RTMPTS, To decrypt chunk/socket takes both sides time in no small way. This is inefficient for real-time communications.
  3. Therefore I’m thinking we should leave encryption to only HTTPS.

Structs§

  • The 1536 bytes handshake data. This respectively consists of following parts:
  • Bytes to indicate Flash Player version/Flash Media Server version.

Enums§