1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef _WEBRTC_BASE_CRYPTSTRING_H_ 12 #define _WEBRTC_BASE_CRYPTSTRING_H_ 13 14 #include <string.h> 15 16 #include <string> 17 #include <vector> 18 19 #include "webrtc/base/linked_ptr.h" 20 #include "webrtc/base/scoped_ptr.h" 21 22 namespace rtc { 23 24 class CryptStringImpl { 25 public: ~CryptStringImpl()26 virtual ~CryptStringImpl() {} 27 virtual size_t GetLength() const = 0; 28 virtual void CopyTo(char * dest, bool nullterminate) const = 0; 29 virtual std::string UrlEncode() const = 0; 30 virtual CryptStringImpl * Copy() const = 0; 31 virtual void CopyRawTo(std::vector<unsigned char> * dest) const = 0; 32 }; 33 34 class EmptyCryptStringImpl : public CryptStringImpl { 35 public: ~EmptyCryptStringImpl()36 ~EmptyCryptStringImpl() override {} 37 size_t GetLength() const override; 38 void CopyTo(char* dest, bool nullterminate) const override; 39 std::string UrlEncode() const override; 40 CryptStringImpl* Copy() const override; 41 void CopyRawTo(std::vector<unsigned char>* dest) const override; 42 }; 43 44 class CryptString { 45 public: 46 CryptString(); GetLength()47 size_t GetLength() const { return impl_->GetLength(); } CopyTo(char * dest,bool nullterminate)48 void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); } 49 CryptString(const CryptString& other); 50 explicit CryptString(const CryptStringImpl& impl); 51 ~CryptString(); 52 CryptString & operator=(const CryptString & other) { 53 if (this != &other) { 54 impl_.reset(other.impl_->Copy()); 55 } 56 return *this; 57 } Clear()58 void Clear() { impl_.reset(new EmptyCryptStringImpl()); } UrlEncode()59 std::string UrlEncode() const { return impl_->UrlEncode(); } CopyRawTo(std::vector<unsigned char> * dest)60 void CopyRawTo(std::vector<unsigned char> * dest) const { 61 return impl_->CopyRawTo(dest); 62 } 63 64 private: 65 scoped_ptr<const CryptStringImpl> impl_; 66 }; 67 68 69 // Used for constructing strings where a password is involved and we 70 // need to ensure that we zero memory afterwards 71 class FormatCryptString { 72 public: FormatCryptString()73 FormatCryptString() { 74 storage_ = new char[32]; 75 capacity_ = 32; 76 length_ = 0; 77 storage_[0] = 0; 78 } 79 Append(const std::string & text)80 void Append(const std::string & text) { 81 Append(text.data(), text.length()); 82 } 83 Append(const char * data,size_t length)84 void Append(const char * data, size_t length) { 85 EnsureStorage(length_ + length + 1); 86 memcpy(storage_ + length_, data, length); 87 length_ += length; 88 storage_[length_] = '\0'; 89 } 90 Append(const CryptString * password)91 void Append(const CryptString * password) { 92 size_t len = password->GetLength(); 93 EnsureStorage(length_ + len + 1); 94 password->CopyTo(storage_ + length_, true); 95 length_ += len; 96 } 97 GetLength()98 size_t GetLength() { 99 return length_; 100 } 101 GetData()102 const char * GetData() { 103 return storage_; 104 } 105 106 107 // Ensures storage of at least n bytes EnsureStorage(size_t n)108 void EnsureStorage(size_t n) { 109 if (capacity_ >= n) { 110 return; 111 } 112 113 size_t old_capacity = capacity_; 114 char * old_storage = storage_; 115 116 for (;;) { 117 capacity_ *= 2; 118 if (capacity_ >= n) 119 break; 120 } 121 122 storage_ = new char[capacity_]; 123 124 if (old_capacity) { 125 memcpy(storage_, old_storage, length_); 126 127 // zero memory in a way that an optimizer won't optimize it out 128 old_storage[0] = 0; 129 for (size_t i = 1; i < old_capacity; i++) { 130 old_storage[i] = old_storage[i - 1]; 131 } 132 delete[] old_storage; 133 } 134 } 135 ~FormatCryptString()136 ~FormatCryptString() { 137 if (capacity_) { 138 storage_[0] = 0; 139 for (size_t i = 1; i < capacity_; i++) { 140 storage_[i] = storage_[i - 1]; 141 } 142 } 143 delete[] storage_; 144 } 145 private: 146 char * storage_; 147 size_t capacity_; 148 size_t length_; 149 }; 150 151 class InsecureCryptStringImpl : public CryptStringImpl { 152 public: password()153 std::string& password() { return password_; } password()154 const std::string& password() const { return password_; } 155 156 ~InsecureCryptStringImpl() override = default; 157 size_t GetLength() const override; 158 void CopyTo(char* dest, bool nullterminate) const override; 159 std::string UrlEncode() const override; 160 CryptStringImpl* Copy() const override; 161 void CopyRawTo(std::vector<unsigned char>* dest) const override; 162 163 private: 164 std::string password_; 165 }; 166 167 } 168 169 #endif // _WEBRTC_BASE_CRYPTSTRING_H_ 170