blob: f43057d8f0f892a6b7a92ded8e58d0c5f187b5a2 [file] [log] [blame]
henrike@webrtc.org2c7d1b32014-05-12 18:03:09 +00001/*
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
22namespace rtc {
23
24class CryptStringImpl {
25public:
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
34class EmptyCryptStringImpl : public CryptStringImpl {
35public:
36 virtual ~EmptyCryptStringImpl() {}
37 virtual size_t GetLength() const { return 0; }
38 virtual void CopyTo(char * dest, bool nullterminate) const {
39 if (nullterminate) {
40 *dest = '\0';
41 }
42 }
43 virtual std::string UrlEncode() const { return ""; }
44 virtual CryptStringImpl * Copy() const { return new EmptyCryptStringImpl(); }
45 virtual void CopyRawTo(std::vector<unsigned char> * dest) const {
46 dest->clear();
47 }
48};
49
50class CryptString {
51public:
52 CryptString() : impl_(new EmptyCryptStringImpl()) {}
53 size_t GetLength() const { return impl_->GetLength(); }
54 void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); }
55 CryptString(const CryptString & other) : impl_(other.impl_->Copy()) {}
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 }
63 void Clear() { impl_.reset(new EmptyCryptStringImpl()); }
64 std::string UrlEncode() const { return impl_->UrlEncode(); }
65 void CopyRawTo(std::vector<unsigned char> * dest) const {
66 return impl_->CopyRawTo(dest);
67 }
68
69private:
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
76class FormatCryptString {
77public:
78 FormatCryptString() {
79 storage_ = new char[32];
80 capacity_ = 32;
81 length_ = 0;
82 storage_[0] = 0;
83 }
84
85 void Append(const std::string & text) {
86 Append(text.data(), text.length());
87 }
88
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
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
103 size_t GetLength() {
104 return length_;
105 }
106
107 const char * GetData() {
108 return storage_;
109 }
110
111
112 // Ensures storage of at least n bytes
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
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 }
150private:
151 char * storage_;
152 size_t capacity_;
153 size_t length_;
154};
155
156class InsecureCryptStringImpl : public CryptStringImpl {
157 public:
158 std::string& password() { return password_; }
159 const std::string& password() const { return password_; }
160
161 virtual ~InsecureCryptStringImpl() {}
162 virtual size_t GetLength() const { return password_.size(); }
163 virtual void CopyTo(char * dest, bool nullterminate) const {
164 memcpy(dest, password_.data(), password_.size());
165 if (nullterminate) dest[password_.size()] = 0;
166 }
167 virtual std::string UrlEncode() const { return password_; }
168 virtual CryptStringImpl * Copy() const {
169 InsecureCryptStringImpl * copy = new InsecureCryptStringImpl;
170 copy->password() = password_;
171 return copy;
172 }
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_