blob: 03b38c462f9e3efd73a15b3891e56eecf5d3f613 [file] [log] [blame]
deadbeeff137e972017-03-23 15:45:49 -07001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_BASE_CRYPTSTRING_H_
12#define RTC_BASE_CRYPTSTRING_H_
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020013
14#include <string.h>
15
16#include <memory>
17#include <string>
18#include <vector>
19
20namespace rtc {
21
22class CryptStringImpl {
23public:
24 virtual ~CryptStringImpl() {}
25 virtual size_t GetLength() const = 0;
26 virtual void CopyTo(char * dest, bool nullterminate) const = 0;
27 virtual std::string UrlEncode() const = 0;
28 virtual CryptStringImpl * Copy() const = 0;
29 virtual void CopyRawTo(std::vector<unsigned char> * dest) const = 0;
30};
31
32class EmptyCryptStringImpl : public CryptStringImpl {
33public:
34 ~EmptyCryptStringImpl() override {}
35 size_t GetLength() const override;
36 void CopyTo(char* dest, bool nullterminate) const override;
37 std::string UrlEncode() const override;
38 CryptStringImpl* Copy() const override;
39 void CopyRawTo(std::vector<unsigned char>* dest) const override;
40};
41
42class CryptString {
43 public:
44 CryptString();
45 size_t GetLength() const { return impl_->GetLength(); }
46 void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); }
47 CryptString(const CryptString& other);
48 explicit CryptString(const CryptStringImpl& impl);
49 ~CryptString();
50 CryptString & operator=(const CryptString & other) {
51 if (this != &other) {
52 impl_.reset(other.impl_->Copy());
53 }
54 return *this;
55 }
56 void Clear() { impl_.reset(new EmptyCryptStringImpl()); }
57 std::string UrlEncode() const { return impl_->UrlEncode(); }
58 void CopyRawTo(std::vector<unsigned char> * dest) const {
59 return impl_->CopyRawTo(dest);
60 }
61
62 private:
63 std::unique_ptr<const CryptStringImpl> impl_;
64};
deadbeeff137e972017-03-23 15:45:49 -070065
66
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020067// Used for constructing strings where a password is involved and we
68// need to ensure that we zero memory afterwards
69class FormatCryptString {
70public:
71 FormatCryptString() {
72 storage_ = new char[32];
73 capacity_ = 32;
74 length_ = 0;
75 storage_[0] = 0;
76 }
Henrik Kjellanderc0362762017-06-29 08:03:04 +020077
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020078 void Append(const std::string & text) {
79 Append(text.data(), text.length());
80 }
deadbeeff137e972017-03-23 15:45:49 -070081
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020082 void Append(const char * data, size_t length) {
83 EnsureStorage(length_ + length + 1);
84 memcpy(storage_ + length_, data, length);
85 length_ += length;
86 storage_[length_] = '\0';
87 }
Henrik Kjellanderc0362762017-06-29 08:03:04 +020088
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020089 void Append(const CryptString * password) {
90 size_t len = password->GetLength();
91 EnsureStorage(length_ + len + 1);
92 password->CopyTo(storage_ + length_, true);
93 length_ += len;
94 }
95
96 size_t GetLength() {
97 return length_;
98 }
99
100 const char * GetData() {
101 return storage_;
102 }
103
104
105 // Ensures storage of at least n bytes
106 void EnsureStorage(size_t n) {
107 if (capacity_ >= n) {
108 return;
109 }
110
111 size_t old_capacity = capacity_;
112 char * old_storage = storage_;
113
114 for (;;) {
115 capacity_ *= 2;
116 if (capacity_ >= n)
117 break;
118 }
119
120 storage_ = new char[capacity_];
121
122 if (old_capacity) {
123 memcpy(storage_, old_storage, length_);
Henrik Kjellanderc0362762017-06-29 08:03:04 +0200124
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200125 // zero memory in a way that an optimizer won't optimize it out
126 old_storage[0] = 0;
127 for (size_t i = 1; i < old_capacity; i++) {
128 old_storage[i] = old_storage[i - 1];
129 }
130 delete[] old_storage;
131 }
Henrik Kjellanderc0362762017-06-29 08:03:04 +0200132 }
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200133
134 ~FormatCryptString() {
135 if (capacity_) {
136 storage_[0] = 0;
137 for (size_t i = 1; i < capacity_; i++) {
138 storage_[i] = storage_[i - 1];
139 }
140 }
141 delete[] storage_;
142 }
143private:
144 char * storage_;
145 size_t capacity_;
146 size_t length_;
147};
148
149class InsecureCryptStringImpl : public CryptStringImpl {
150 public:
151 std::string& password() { return password_; }
152 const std::string& password() const { return password_; }
153
154 ~InsecureCryptStringImpl() override = default;
155 size_t GetLength() const override;
156 void CopyTo(char* dest, bool nullterminate) const override;
157 std::string UrlEncode() const override;
158 CryptStringImpl* Copy() const override;
159 void CopyRawTo(std::vector<unsigned char>* dest) const override;
160
161 private:
162 std::string password_;
163};
164
165}
166
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200167#endif // RTC_BASE_CRYPTSTRING_H_