blob: adaac2f36bc21e8247709ae0c0617f190a5d41dd [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +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
jbauch555604a2016-04-26 03:13:22 -070016#include <memory>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017#include <string>
18#include <vector>
19
20#include "webrtc/base/linked_ptr.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000021
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:
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000036 ~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;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000042};
43
44class CryptString {
jbauch555604a2016-04-26 03:13:22 -070045 public:
46 CryptString();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047 size_t GetLength() const { return impl_->GetLength(); }
48 void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000049 CryptString(const CryptString& other);
50 explicit CryptString(const CryptStringImpl& impl);
51 ~CryptString();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000052 CryptString & operator=(const CryptString & other) {
53 if (this != &other) {
54 impl_.reset(other.impl_->Copy());
55 }
56 return *this;
57 }
58 void Clear() { impl_.reset(new EmptyCryptStringImpl()); }
59 std::string UrlEncode() const { return impl_->UrlEncode(); }
60 void CopyRawTo(std::vector<unsigned char> * dest) const {
61 return impl_->CopyRawTo(dest);
62 }
jbauch555604a2016-04-26 03:13:22 -070063
64 private:
65 std::unique_ptr<const CryptStringImpl> impl_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000066};
67
68
69// Used for constructing strings where a password is involved and we
70// need to ensure that we zero memory afterwards
71class FormatCryptString {
72public:
73 FormatCryptString() {
74 storage_ = new char[32];
75 capacity_ = 32;
76 length_ = 0;
77 storage_[0] = 0;
78 }
79
80 void Append(const std::string & text) {
81 Append(text.data(), text.length());
82 }
83
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
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
98 size_t GetLength() {
99 return length_;
100 }
101
102 const char * GetData() {
103 return storage_;
104 }
105
106
107 // Ensures storage of at least n bytes
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
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 }
145private:
146 char * storage_;
147 size_t capacity_;
148 size_t length_;
149};
150
151class InsecureCryptStringImpl : public CryptStringImpl {
152 public:
153 std::string& password() { return password_; }
154 const std::string& password() const { return password_; }
155
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000156 ~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
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000163 private:
164 std::string password_;
165};
166
167}
168
169#endif // _WEBRTC_BASE_CRYPTSTRING_H_