Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=2 et sw=2 tw=80: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 5 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | // Original author: ekr@rtfm.com |
michael@0 | 8 | |
michael@0 | 9 | #ifndef transportlayerdtls_h__ |
michael@0 | 10 | #define transportlayerdtls_h__ |
michael@0 | 11 | |
michael@0 | 12 | #include <queue> |
michael@0 | 13 | |
michael@0 | 14 | #include "sigslot.h" |
michael@0 | 15 | |
michael@0 | 16 | #include "mozilla/RefPtr.h" |
michael@0 | 17 | #include "mozilla/Scoped.h" |
michael@0 | 18 | #include "nsCOMPtr.h" |
michael@0 | 19 | #include "nsIEventTarget.h" |
michael@0 | 20 | #include "nsITimer.h" |
michael@0 | 21 | #include "ScopedNSSTypes.h" |
michael@0 | 22 | #include "m_cpp_utils.h" |
michael@0 | 23 | #include "dtlsidentity.h" |
michael@0 | 24 | #include "transportflow.h" |
michael@0 | 25 | #include "transportlayer.h" |
michael@0 | 26 | |
michael@0 | 27 | namespace mozilla { |
michael@0 | 28 | |
michael@0 | 29 | struct Packet; |
michael@0 | 30 | |
michael@0 | 31 | class TransportLayerNSPRAdapter { |
michael@0 | 32 | public: |
michael@0 | 33 | TransportLayerNSPRAdapter(TransportLayer *output) : |
michael@0 | 34 | output_(output), |
michael@0 | 35 | input_() {} |
michael@0 | 36 | |
michael@0 | 37 | void PacketReceived(const void *data, int32_t len); |
michael@0 | 38 | int32_t Read(void *data, int32_t len); |
michael@0 | 39 | int32_t Write(const void *buf, int32_t length); |
michael@0 | 40 | |
michael@0 | 41 | private: |
michael@0 | 42 | DISALLOW_COPY_ASSIGN(TransportLayerNSPRAdapter); |
michael@0 | 43 | |
michael@0 | 44 | TransportLayer *output_; |
michael@0 | 45 | std::queue<Packet *> input_; |
michael@0 | 46 | }; |
michael@0 | 47 | |
michael@0 | 48 | class TransportLayerDtls : public TransportLayer { |
michael@0 | 49 | public: |
michael@0 | 50 | TransportLayerDtls() : |
michael@0 | 51 | TransportLayer(DGRAM), |
michael@0 | 52 | role_(CLIENT), |
michael@0 | 53 | verification_mode_(VERIFY_UNSET), |
michael@0 | 54 | ssl_fd_(nullptr), |
michael@0 | 55 | auth_hook_called_(false), |
michael@0 | 56 | cert_ok_(false) {} |
michael@0 | 57 | |
michael@0 | 58 | virtual ~TransportLayerDtls(); |
michael@0 | 59 | |
michael@0 | 60 | enum Role { CLIENT, SERVER}; |
michael@0 | 61 | enum Verification { VERIFY_UNSET, VERIFY_ALLOW_ALL, VERIFY_DIGEST}; |
michael@0 | 62 | const static size_t kMaxDigestLength = HASH_LENGTH_MAX; |
michael@0 | 63 | |
michael@0 | 64 | // DTLS-specific operations |
michael@0 | 65 | void SetRole(Role role) { role_ = role;} |
michael@0 | 66 | Role role() { return role_; } |
michael@0 | 67 | |
michael@0 | 68 | void SetIdentity(const RefPtr<DtlsIdentity>& identity) { |
michael@0 | 69 | identity_ = identity; |
michael@0 | 70 | } |
michael@0 | 71 | nsresult SetVerificationAllowAll(); |
michael@0 | 72 | nsresult SetVerificationDigest(const std::string digest_algorithm, |
michael@0 | 73 | const unsigned char *digest_value, |
michael@0 | 74 | size_t digest_len); |
michael@0 | 75 | |
michael@0 | 76 | nsresult SetSrtpCiphers(std::vector<uint16_t> ciphers); |
michael@0 | 77 | nsresult GetSrtpCipher(uint16_t *cipher); |
michael@0 | 78 | |
michael@0 | 79 | nsresult ExportKeyingMaterial(const std::string& label, |
michael@0 | 80 | bool use_context, |
michael@0 | 81 | const std::string& context, |
michael@0 | 82 | unsigned char *out, |
michael@0 | 83 | unsigned int outlen); |
michael@0 | 84 | |
michael@0 | 85 | const CERTCertificate *GetPeerCert() const { |
michael@0 | 86 | return peer_cert_; |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | // Transport layer overrides. |
michael@0 | 90 | virtual nsresult InitInternal(); |
michael@0 | 91 | virtual void WasInserted(); |
michael@0 | 92 | virtual TransportResult SendPacket(const unsigned char *data, size_t len); |
michael@0 | 93 | |
michael@0 | 94 | // Signals |
michael@0 | 95 | void StateChange(TransportLayer *layer, State state); |
michael@0 | 96 | void PacketReceived(TransportLayer* layer, const unsigned char *data, |
michael@0 | 97 | size_t len); |
michael@0 | 98 | |
michael@0 | 99 | TRANSPORT_LAYER_ID("dtls") |
michael@0 | 100 | |
michael@0 | 101 | private: |
michael@0 | 102 | DISALLOW_COPY_ASSIGN(TransportLayerDtls); |
michael@0 | 103 | |
michael@0 | 104 | // A single digest to check |
michael@0 | 105 | class VerificationDigest { |
michael@0 | 106 | public: |
michael@0 | 107 | VerificationDigest(std::string algorithm, |
michael@0 | 108 | const unsigned char *value, size_t len) { |
michael@0 | 109 | MOZ_ASSERT(len <= sizeof(value_)); |
michael@0 | 110 | |
michael@0 | 111 | algorithm_ = algorithm; |
michael@0 | 112 | memcpy(value_, value, len); |
michael@0 | 113 | len_ = len; |
michael@0 | 114 | } |
michael@0 | 115 | |
michael@0 | 116 | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VerificationDigest) |
michael@0 | 117 | |
michael@0 | 118 | std::string algorithm_; |
michael@0 | 119 | size_t len_; |
michael@0 | 120 | unsigned char value_[kMaxDigestLength]; |
michael@0 | 121 | |
michael@0 | 122 | private: |
michael@0 | 123 | DISALLOW_COPY_ASSIGN(VerificationDigest); |
michael@0 | 124 | }; |
michael@0 | 125 | |
michael@0 | 126 | |
michael@0 | 127 | bool Setup(); |
michael@0 | 128 | void Handshake(); |
michael@0 | 129 | |
michael@0 | 130 | static SECStatus GetClientAuthDataHook(void *arg, PRFileDesc *fd, |
michael@0 | 131 | CERTDistNames *caNames, |
michael@0 | 132 | CERTCertificate **pRetCert, |
michael@0 | 133 | SECKEYPrivateKey **pRetKey); |
michael@0 | 134 | static SECStatus AuthCertificateHook(void *arg, |
michael@0 | 135 | PRFileDesc *fd, |
michael@0 | 136 | PRBool checksig, |
michael@0 | 137 | PRBool isServer); |
michael@0 | 138 | SECStatus AuthCertificateHook(PRFileDesc *fd, |
michael@0 | 139 | PRBool checksig, |
michael@0 | 140 | PRBool isServer); |
michael@0 | 141 | |
michael@0 | 142 | static void TimerCallback(nsITimer *timer, void *arg); |
michael@0 | 143 | |
michael@0 | 144 | SECStatus CheckDigest(const RefPtr<VerificationDigest>& digest, |
michael@0 | 145 | CERTCertificate *cert); |
michael@0 | 146 | |
michael@0 | 147 | RefPtr<DtlsIdentity> identity_; |
michael@0 | 148 | std::vector<uint16_t> srtp_ciphers_; |
michael@0 | 149 | |
michael@0 | 150 | Role role_; |
michael@0 | 151 | Verification verification_mode_; |
michael@0 | 152 | std::vector<RefPtr<VerificationDigest> > digests_; |
michael@0 | 153 | |
michael@0 | 154 | // Must delete nspr_io_adapter after ssl_fd_ b/c ssl_fd_ causes an alert |
michael@0 | 155 | // (ssl_fd_ contains an un-owning pointer to nspr_io_adapter_) |
michael@0 | 156 | ScopedDeletePtr<TransportLayerNSPRAdapter> nspr_io_adapter_; |
michael@0 | 157 | ScopedPRFileDesc ssl_fd_; |
michael@0 | 158 | |
michael@0 | 159 | ScopedCERTCertificate peer_cert_; |
michael@0 | 160 | nsCOMPtr<nsITimer> timer_; |
michael@0 | 161 | bool auth_hook_called_; |
michael@0 | 162 | bool cert_ok_; |
michael@0 | 163 | }; |
michael@0 | 164 | |
michael@0 | 165 | |
michael@0 | 166 | } // close namespace |
michael@0 | 167 | #endif |