1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/mtransport/transportlayerdtls.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,167 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +// Original author: ekr@rtfm.com 1.11 + 1.12 +#ifndef transportlayerdtls_h__ 1.13 +#define transportlayerdtls_h__ 1.14 + 1.15 +#include <queue> 1.16 + 1.17 +#include "sigslot.h" 1.18 + 1.19 +#include "mozilla/RefPtr.h" 1.20 +#include "mozilla/Scoped.h" 1.21 +#include "nsCOMPtr.h" 1.22 +#include "nsIEventTarget.h" 1.23 +#include "nsITimer.h" 1.24 +#include "ScopedNSSTypes.h" 1.25 +#include "m_cpp_utils.h" 1.26 +#include "dtlsidentity.h" 1.27 +#include "transportflow.h" 1.28 +#include "transportlayer.h" 1.29 + 1.30 +namespace mozilla { 1.31 + 1.32 +struct Packet; 1.33 + 1.34 +class TransportLayerNSPRAdapter { 1.35 + public: 1.36 + TransportLayerNSPRAdapter(TransportLayer *output) : 1.37 + output_(output), 1.38 + input_() {} 1.39 + 1.40 + void PacketReceived(const void *data, int32_t len); 1.41 + int32_t Read(void *data, int32_t len); 1.42 + int32_t Write(const void *buf, int32_t length); 1.43 + 1.44 + private: 1.45 + DISALLOW_COPY_ASSIGN(TransportLayerNSPRAdapter); 1.46 + 1.47 + TransportLayer *output_; 1.48 + std::queue<Packet *> input_; 1.49 +}; 1.50 + 1.51 +class TransportLayerDtls : public TransportLayer { 1.52 + public: 1.53 + TransportLayerDtls() : 1.54 + TransportLayer(DGRAM), 1.55 + role_(CLIENT), 1.56 + verification_mode_(VERIFY_UNSET), 1.57 + ssl_fd_(nullptr), 1.58 + auth_hook_called_(false), 1.59 + cert_ok_(false) {} 1.60 + 1.61 + virtual ~TransportLayerDtls(); 1.62 + 1.63 + enum Role { CLIENT, SERVER}; 1.64 + enum Verification { VERIFY_UNSET, VERIFY_ALLOW_ALL, VERIFY_DIGEST}; 1.65 + const static size_t kMaxDigestLength = HASH_LENGTH_MAX; 1.66 + 1.67 + // DTLS-specific operations 1.68 + void SetRole(Role role) { role_ = role;} 1.69 + Role role() { return role_; } 1.70 + 1.71 + void SetIdentity(const RefPtr<DtlsIdentity>& identity) { 1.72 + identity_ = identity; 1.73 + } 1.74 + nsresult SetVerificationAllowAll(); 1.75 + nsresult SetVerificationDigest(const std::string digest_algorithm, 1.76 + const unsigned char *digest_value, 1.77 + size_t digest_len); 1.78 + 1.79 + nsresult SetSrtpCiphers(std::vector<uint16_t> ciphers); 1.80 + nsresult GetSrtpCipher(uint16_t *cipher); 1.81 + 1.82 + nsresult ExportKeyingMaterial(const std::string& label, 1.83 + bool use_context, 1.84 + const std::string& context, 1.85 + unsigned char *out, 1.86 + unsigned int outlen); 1.87 + 1.88 + const CERTCertificate *GetPeerCert() const { 1.89 + return peer_cert_; 1.90 + } 1.91 + 1.92 + // Transport layer overrides. 1.93 + virtual nsresult InitInternal(); 1.94 + virtual void WasInserted(); 1.95 + virtual TransportResult SendPacket(const unsigned char *data, size_t len); 1.96 + 1.97 + // Signals 1.98 + void StateChange(TransportLayer *layer, State state); 1.99 + void PacketReceived(TransportLayer* layer, const unsigned char *data, 1.100 + size_t len); 1.101 + 1.102 + TRANSPORT_LAYER_ID("dtls") 1.103 + 1.104 + private: 1.105 + DISALLOW_COPY_ASSIGN(TransportLayerDtls); 1.106 + 1.107 + // A single digest to check 1.108 + class VerificationDigest { 1.109 + public: 1.110 + VerificationDigest(std::string algorithm, 1.111 + const unsigned char *value, size_t len) { 1.112 + MOZ_ASSERT(len <= sizeof(value_)); 1.113 + 1.114 + algorithm_ = algorithm; 1.115 + memcpy(value_, value, len); 1.116 + len_ = len; 1.117 + } 1.118 + 1.119 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VerificationDigest) 1.120 + 1.121 + std::string algorithm_; 1.122 + size_t len_; 1.123 + unsigned char value_[kMaxDigestLength]; 1.124 + 1.125 + private: 1.126 + DISALLOW_COPY_ASSIGN(VerificationDigest); 1.127 + }; 1.128 + 1.129 + 1.130 + bool Setup(); 1.131 + void Handshake(); 1.132 + 1.133 + static SECStatus GetClientAuthDataHook(void *arg, PRFileDesc *fd, 1.134 + CERTDistNames *caNames, 1.135 + CERTCertificate **pRetCert, 1.136 + SECKEYPrivateKey **pRetKey); 1.137 + static SECStatus AuthCertificateHook(void *arg, 1.138 + PRFileDesc *fd, 1.139 + PRBool checksig, 1.140 + PRBool isServer); 1.141 + SECStatus AuthCertificateHook(PRFileDesc *fd, 1.142 + PRBool checksig, 1.143 + PRBool isServer); 1.144 + 1.145 + static void TimerCallback(nsITimer *timer, void *arg); 1.146 + 1.147 + SECStatus CheckDigest(const RefPtr<VerificationDigest>& digest, 1.148 + CERTCertificate *cert); 1.149 + 1.150 + RefPtr<DtlsIdentity> identity_; 1.151 + std::vector<uint16_t> srtp_ciphers_; 1.152 + 1.153 + Role role_; 1.154 + Verification verification_mode_; 1.155 + std::vector<RefPtr<VerificationDigest> > digests_; 1.156 + 1.157 + // Must delete nspr_io_adapter after ssl_fd_ b/c ssl_fd_ causes an alert 1.158 + // (ssl_fd_ contains an un-owning pointer to nspr_io_adapter_) 1.159 + ScopedDeletePtr<TransportLayerNSPRAdapter> nspr_io_adapter_; 1.160 + ScopedPRFileDesc ssl_fd_; 1.161 + 1.162 + ScopedCERTCertificate peer_cert_; 1.163 + nsCOMPtr<nsITimer> timer_; 1.164 + bool auth_hook_called_; 1.165 + bool cert_ok_; 1.166 +}; 1.167 + 1.168 + 1.169 +} // close namespace 1.170 +#endif