diff -r 000000000000 -r 6474c204b198 media/mtransport/transportlayerdtls.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/media/mtransport/transportlayerdtls.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Original author: ekr@rtfm.com + +#ifndef transportlayerdtls_h__ +#define transportlayerdtls_h__ + +#include + +#include "sigslot.h" + +#include "mozilla/RefPtr.h" +#include "mozilla/Scoped.h" +#include "nsCOMPtr.h" +#include "nsIEventTarget.h" +#include "nsITimer.h" +#include "ScopedNSSTypes.h" +#include "m_cpp_utils.h" +#include "dtlsidentity.h" +#include "transportflow.h" +#include "transportlayer.h" + +namespace mozilla { + +struct Packet; + +class TransportLayerNSPRAdapter { + public: + TransportLayerNSPRAdapter(TransportLayer *output) : + output_(output), + input_() {} + + void PacketReceived(const void *data, int32_t len); + int32_t Read(void *data, int32_t len); + int32_t Write(const void *buf, int32_t length); + + private: + DISALLOW_COPY_ASSIGN(TransportLayerNSPRAdapter); + + TransportLayer *output_; + std::queue input_; +}; + +class TransportLayerDtls : public TransportLayer { + public: + TransportLayerDtls() : + TransportLayer(DGRAM), + role_(CLIENT), + verification_mode_(VERIFY_UNSET), + ssl_fd_(nullptr), + auth_hook_called_(false), + cert_ok_(false) {} + + virtual ~TransportLayerDtls(); + + enum Role { CLIENT, SERVER}; + enum Verification { VERIFY_UNSET, VERIFY_ALLOW_ALL, VERIFY_DIGEST}; + const static size_t kMaxDigestLength = HASH_LENGTH_MAX; + + // DTLS-specific operations + void SetRole(Role role) { role_ = role;} + Role role() { return role_; } + + void SetIdentity(const RefPtr& identity) { + identity_ = identity; + } + nsresult SetVerificationAllowAll(); + nsresult SetVerificationDigest(const std::string digest_algorithm, + const unsigned char *digest_value, + size_t digest_len); + + nsresult SetSrtpCiphers(std::vector ciphers); + nsresult GetSrtpCipher(uint16_t *cipher); + + nsresult ExportKeyingMaterial(const std::string& label, + bool use_context, + const std::string& context, + unsigned char *out, + unsigned int outlen); + + const CERTCertificate *GetPeerCert() const { + return peer_cert_; + } + + // Transport layer overrides. + virtual nsresult InitInternal(); + virtual void WasInserted(); + virtual TransportResult SendPacket(const unsigned char *data, size_t len); + + // Signals + void StateChange(TransportLayer *layer, State state); + void PacketReceived(TransportLayer* layer, const unsigned char *data, + size_t len); + + TRANSPORT_LAYER_ID("dtls") + + private: + DISALLOW_COPY_ASSIGN(TransportLayerDtls); + + // A single digest to check + class VerificationDigest { + public: + VerificationDigest(std::string algorithm, + const unsigned char *value, size_t len) { + MOZ_ASSERT(len <= sizeof(value_)); + + algorithm_ = algorithm; + memcpy(value_, value, len); + len_ = len; + } + + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VerificationDigest) + + std::string algorithm_; + size_t len_; + unsigned char value_[kMaxDigestLength]; + + private: + DISALLOW_COPY_ASSIGN(VerificationDigest); + }; + + + bool Setup(); + void Handshake(); + + static SECStatus GetClientAuthDataHook(void *arg, PRFileDesc *fd, + CERTDistNames *caNames, + CERTCertificate **pRetCert, + SECKEYPrivateKey **pRetKey); + static SECStatus AuthCertificateHook(void *arg, + PRFileDesc *fd, + PRBool checksig, + PRBool isServer); + SECStatus AuthCertificateHook(PRFileDesc *fd, + PRBool checksig, + PRBool isServer); + + static void TimerCallback(nsITimer *timer, void *arg); + + SECStatus CheckDigest(const RefPtr& digest, + CERTCertificate *cert); + + RefPtr identity_; + std::vector srtp_ciphers_; + + Role role_; + Verification verification_mode_; + std::vector > digests_; + + // Must delete nspr_io_adapter after ssl_fd_ b/c ssl_fd_ causes an alert + // (ssl_fd_ contains an un-owning pointer to nspr_io_adapter_) + ScopedDeletePtr nspr_io_adapter_; + ScopedPRFileDesc ssl_fd_; + + ScopedCERTCertificate peer_cert_; + nsCOMPtr timer_; + bool auth_hook_called_; + bool cert_ok_; +}; + + +} // close namespace +#endif