• 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   ~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