• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   virtual ~EmptyCryptStringImpl() {}
GetLength()37   virtual size_t GetLength() const { return 0; }
CopyTo(char * dest,bool nullterminate)38   virtual void CopyTo(char * dest, bool nullterminate) const {
39     if (nullterminate) {
40       *dest = '\0';
41     }
42   }
UrlEncode()43   virtual std::string UrlEncode() const { return ""; }
Copy()44   virtual CryptStringImpl * Copy() const { return new EmptyCryptStringImpl(); }
CopyRawTo(std::vector<unsigned char> * dest)45   virtual void CopyRawTo(std::vector<unsigned char> * dest) const {
46     dest->clear();
47   }
48 };
49 
50 class CryptString {
51 public:
CryptString()52   CryptString() : impl_(new EmptyCryptStringImpl()) {}
GetLength()53   size_t GetLength() const { return impl_->GetLength(); }
CopyTo(char * dest,bool nullterminate)54   void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); }
CryptString(const CryptString & other)55   CryptString(const CryptString & other) : impl_(other.impl_->Copy()) {}
CryptString(const CryptStringImpl & impl)56   explicit CryptString(const CryptStringImpl & impl) : impl_(impl.Copy()) {}
57   CryptString & operator=(const CryptString & other) {
58     if (this != &other) {
59       impl_.reset(other.impl_->Copy());
60     }
61     return *this;
62   }
Clear()63   void Clear() { impl_.reset(new EmptyCryptStringImpl()); }
UrlEncode()64   std::string UrlEncode() const { return impl_->UrlEncode(); }
CopyRawTo(std::vector<unsigned char> * dest)65   void CopyRawTo(std::vector<unsigned char> * dest) const {
66     return impl_->CopyRawTo(dest);
67   }
68 
69 private:
70   scoped_ptr<const CryptStringImpl> impl_;
71 };
72 
73 
74 // Used for constructing strings where a password is involved and we
75 // need to ensure that we zero memory afterwards
76 class FormatCryptString {
77 public:
FormatCryptString()78   FormatCryptString() {
79     storage_ = new char[32];
80     capacity_ = 32;
81     length_ = 0;
82     storage_[0] = 0;
83   }
84 
Append(const std::string & text)85   void Append(const std::string & text) {
86     Append(text.data(), text.length());
87   }
88 
Append(const char * data,size_t length)89   void Append(const char * data, size_t length) {
90     EnsureStorage(length_ + length + 1);
91     memcpy(storage_ + length_, data, length);
92     length_ += length;
93     storage_[length_] = '\0';
94   }
95 
Append(const CryptString * password)96   void Append(const CryptString * password) {
97     size_t len = password->GetLength();
98     EnsureStorage(length_ + len + 1);
99     password->CopyTo(storage_ + length_, true);
100     length_ += len;
101   }
102 
GetLength()103   size_t GetLength() {
104     return length_;
105   }
106 
GetData()107   const char * GetData() {
108     return storage_;
109   }
110 
111 
112   // Ensures storage of at least n bytes
EnsureStorage(size_t n)113   void EnsureStorage(size_t n) {
114     if (capacity_ >= n) {
115       return;
116     }
117 
118     size_t old_capacity = capacity_;
119     char * old_storage = storage_;
120 
121     for (;;) {
122       capacity_ *= 2;
123       if (capacity_ >= n)
124         break;
125     }
126 
127     storage_ = new char[capacity_];
128 
129     if (old_capacity) {
130       memcpy(storage_, old_storage, length_);
131 
132       // zero memory in a way that an optimizer won't optimize it out
133       old_storage[0] = 0;
134       for (size_t i = 1; i < old_capacity; i++) {
135         old_storage[i] = old_storage[i - 1];
136       }
137       delete[] old_storage;
138     }
139   }
140 
~FormatCryptString()141   ~FormatCryptString() {
142     if (capacity_) {
143       storage_[0] = 0;
144       for (size_t i = 1; i < capacity_; i++) {
145         storage_[i] = storage_[i - 1];
146       }
147     }
148     delete[] storage_;
149   }
150 private:
151   char * storage_;
152   size_t capacity_;
153   size_t length_;
154 };
155 
156 class InsecureCryptStringImpl : public CryptStringImpl {
157  public:
password()158   std::string& password() { return password_; }
password()159   const std::string& password() const { return password_; }
160 
~InsecureCryptStringImpl()161   virtual ~InsecureCryptStringImpl() {}
GetLength()162   virtual size_t GetLength() const { return password_.size(); }
CopyTo(char * dest,bool nullterminate)163   virtual void CopyTo(char * dest, bool nullterminate) const {
164     memcpy(dest, password_.data(), password_.size());
165     if (nullterminate) dest[password_.size()] = 0;
166   }
UrlEncode()167   virtual std::string UrlEncode() const { return password_; }
Copy()168   virtual CryptStringImpl * Copy() const {
169     InsecureCryptStringImpl * copy = new InsecureCryptStringImpl;
170     copy->password() = password_;
171     return copy;
172   }
CopyRawTo(std::vector<unsigned char> * dest)173   virtual void CopyRawTo(std::vector<unsigned char> * dest) const {
174     dest->resize(password_.size());
175     memcpy(&dest->front(), password_.data(), password_.size());
176   }
177  private:
178   std::string password_;
179 };
180 
181 }
182 
183 #endif  // _WEBRTC_BASE_CRYPTSTRING_H_
184