|
1 | 1 | #pragma once |
2 | 2 |
|
| 3 | +#include <cstddef> |
3 | 4 | #include <list> |
4 | 5 | #include <memory> |
5 | 6 | #include <optional> |
6 | 7 | #include <string> |
7 | 8 | #include <string_view> |
8 | | -#include <vector> |
9 | 9 | #include "openssl/bn.h" |
10 | 10 | #include <openssl/x509.h> |
11 | 11 | #include <openssl/dh.h> |
@@ -82,6 +82,15 @@ namespace ncrypto { |
82 | 82 | void* operator new(size_t) = delete; \ |
83 | 83 | void operator delete(void*) = delete; |
84 | 84 |
|
| 85 | +[[noreturn]] inline void unreachable() { |
| 86 | +#ifdef __GNUC__ |
| 87 | + __builtin_unreachable(); |
| 88 | +#elif defined(_MSC_VER) |
| 89 | + __assume(false); |
| 90 | +#else |
| 91 | +#endif |
| 92 | +} |
| 93 | + |
85 | 94 | // ============================================================================ |
86 | 95 | // Error handling utilities |
87 | 96 |
|
@@ -190,30 +199,92 @@ using SSLPointer = DeleteFnPtr<SSL, SSL_free>; |
190 | 199 | using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>; |
191 | 200 | using X509Pointer = DeleteFnPtr<X509, X509_free>; |
192 | 201 |
|
| 202 | +// An unowned, unmanaged pointer to a buffer of data. |
| 203 | +template <typename T> |
| 204 | +struct Buffer { |
| 205 | + T* data = nullptr; |
| 206 | + size_t len = 0; |
| 207 | +}; |
| 208 | + |
| 209 | +// A managed pointer to a buffer of data. When destroyed the underlying |
| 210 | +// buffer will be freed. |
| 211 | +class DataPointer final { |
| 212 | + public: |
| 213 | + static DataPointer Alloc(size_t len); |
| 214 | + |
| 215 | + DataPointer() = default; |
| 216 | + explicit DataPointer(void* data, size_t len); |
| 217 | + explicit DataPointer(const Buffer<void>& buffer); |
| 218 | + DataPointer(DataPointer&& other) noexcept; |
| 219 | + DataPointer& operator=(DataPointer&& other) noexcept; |
| 220 | + NCRYPTO_DISALLOW_COPY(DataPointer) |
| 221 | + ~DataPointer(); |
| 222 | + |
| 223 | + inline bool operator==(std::nullptr_t) noexcept { return data_ == nullptr; } |
| 224 | + inline operator bool() const { return data_ != nullptr; } |
| 225 | + inline void* get() const noexcept { return data_; } |
| 226 | + inline size_t size() const noexcept { return len_; } |
| 227 | + void reset(void* data = nullptr, size_t len = 0); |
| 228 | + void reset(const Buffer<void>& buffer); |
| 229 | + |
| 230 | + // Releases ownership of the underlying data buffer. It is the caller's |
| 231 | + // responsibility to ensure the buffer is appropriately freed. |
| 232 | + Buffer<void> release(); |
| 233 | + |
| 234 | + // Returns a Buffer struct that is a view of the underlying data. |
| 235 | + inline operator const Buffer<void>() const { |
| 236 | + return { |
| 237 | + .data = data_, |
| 238 | + .len = len_, |
| 239 | + }; |
| 240 | + } |
| 241 | + |
| 242 | + private: |
| 243 | + void* data_ = nullptr; |
| 244 | + size_t len_ = 0; |
| 245 | +}; |
| 246 | + |
193 | 247 | class BignumPointer final { |
194 | 248 | public: |
195 | 249 | BignumPointer() = default; |
196 | 250 | explicit BignumPointer(BIGNUM* bignum); |
| 251 | + explicit BignumPointer(const unsigned char* data, size_t len); |
197 | 252 | BignumPointer(BignumPointer&& other) noexcept; |
198 | 253 | BignumPointer& operator=(BignumPointer&& other) noexcept; |
199 | 254 | NCRYPTO_DISALLOW_COPY(BignumPointer) |
200 | 255 | ~BignumPointer(); |
201 | 256 |
|
202 | | - bool operator==(const BignumPointer& other) noexcept; |
203 | | - bool operator==(const BIGNUM* other) noexcept; |
204 | | - inline bool operator==(std::nullptr_t) noexcept { return bn_ == nullptr; } |
| 257 | + int operator<=>(const BignumPointer& other) const noexcept; |
| 258 | + int operator<=>(const BIGNUM* other) const noexcept; |
205 | 259 | inline operator bool() const { return bn_ != nullptr; } |
206 | 260 | inline BIGNUM* get() const noexcept { return bn_.get(); } |
207 | 261 | void reset(BIGNUM* bn = nullptr); |
| 262 | + void reset(const unsigned char* data, size_t len); |
208 | 263 | BIGNUM* release(); |
209 | 264 |
|
210 | | - size_t byteLength(); |
| 265 | + bool isZero() const; |
| 266 | + bool isOne() const; |
211 | 267 |
|
212 | | - std::vector<uint8_t> encode(); |
213 | | - std::vector<uint8_t> encodePadded(size_t size); |
| 268 | + bool setWord(unsigned long w); |
| 269 | + unsigned long getWord() const; |
214 | 270 |
|
215 | | - static std::vector<uint8_t> encode(const BIGNUM* bn); |
216 | | - static std::vector<uint8_t> encodePadded(const BIGNUM* bn, size_t size); |
| 271 | + size_t byteLength() const; |
| 272 | + |
| 273 | + DataPointer toHex() const; |
| 274 | + DataPointer encode() const; |
| 275 | + DataPointer encodePadded(size_t size) const; |
| 276 | + size_t encodeInto(unsigned char* out) const; |
| 277 | + size_t encodePaddedInto(unsigned char* out, size_t size) const; |
| 278 | + |
| 279 | + static BignumPointer New(); |
| 280 | + static BignumPointer NewSecure(); |
| 281 | + static DataPointer Encode(const BIGNUM* bn); |
| 282 | + static DataPointer EncodePadded(const BIGNUM* bn, size_t size); |
| 283 | + static size_t EncodePaddedInto(const BIGNUM* bn, unsigned char* out, size_t size); |
| 284 | + static int GetBitCount(const BIGNUM* bn); |
| 285 | + static int GetByteCount(const BIGNUM* bn); |
| 286 | + static unsigned long GetWord(const BIGNUM* bn); |
| 287 | + static const BIGNUM* One(); |
217 | 288 |
|
218 | 289 | private: |
219 | 290 | DeleteFnPtr<BIGNUM, BN_clear_free> bn_; |
@@ -269,12 +340,6 @@ bool testFipsEnabled(); |
269 | 340 | // ============================================================================ |
270 | 341 | // Various utilities |
271 | 342 |
|
272 | | -template <typename T> |
273 | | -struct Buffer { |
274 | | - T* data = nullptr; |
275 | | - size_t len = 0; |
276 | | -}; |
277 | | - |
278 | 343 | bool CSPRNG(void* buffer, size_t length) NCRYPTO_MUST_USE_RESULT; |
279 | 344 |
|
280 | 345 | // This callback is used to avoid the default passphrase callback in OpenSSL |
@@ -286,6 +351,9 @@ int NoPasswordCallback(char* buf, int size, int rwflag, void* u); |
286 | 351 |
|
287 | 352 | int PasswordCallback(char* buf, int size, int rwflag, void* u); |
288 | 353 |
|
| 354 | +bool SafeX509SubjectAltNamePrint(const BIOPointer& out, X509_EXTENSION* ext); |
| 355 | +bool SafeX509InfoAccessPrint(const BIOPointer& out, X509_EXTENSION* ext); |
| 356 | + |
289 | 357 | // ============================================================================ |
290 | 358 | // SPKAC |
291 | 359 |
|
|