]>
Commit | Line | Data |
---|---|---|
9f95a23c | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
7c673cae FG |
2 | // vim: ts=8 sw=2 smarttab |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net> | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #ifndef CEPH_AUTH_CRYPTO_H | |
16 | #define CEPH_AUTH_CRYPTO_H | |
17 | ||
9f95a23c | 18 | #include "include/common_fwd.h" |
7c673cae FG |
19 | #include "include/types.h" |
20 | #include "include/utime.h" | |
7c673cae FG |
21 | #include "include/buffer.h" |
22 | ||
23 | #include <string> | |
24 | ||
7c673cae FG |
25 | class CryptoKeyContext; |
26 | namespace ceph { class Formatter; } | |
27 | ||
11fdf7f2 TL |
28 | /* |
29 | * Random byte stream generator suitable for cryptographic use | |
30 | */ | |
31 | class CryptoRandom { | |
92f5a8d4 | 32 | public: |
11fdf7f2 TL |
33 | CryptoRandom(); // throws on failure |
34 | ~CryptoRandom(); | |
11fdf7f2 TL |
35 | /// copy up to 256 random bytes into the given buffer. throws on failure |
36 | void get_bytes(char *buf, int len); | |
92f5a8d4 TL |
37 | private: |
38 | static int open_urandom(); | |
39 | const int fd; | |
11fdf7f2 | 40 | }; |
7c673cae FG |
41 | |
42 | /* | |
43 | * some per-key context that is specific to a particular crypto backend | |
44 | */ | |
45 | class CryptoKeyHandler { | |
46 | public: | |
11fdf7f2 TL |
47 | // The maximum size of a single block for all descendants of the class. |
48 | static constexpr std::size_t MAX_BLOCK_SIZE {16}; | |
49 | ||
50 | // A descendant pick-ups one from these and passes it to the ctor template. | |
51 | typedef std::integral_constant<std::size_t, 0> BLOCK_SIZE_0B; | |
52 | typedef std::integral_constant<std::size_t, 16> BLOCK_SIZE_16B; | |
53 | ||
54 | struct in_slice_t { | |
55 | const std::size_t length; | |
56 | const unsigned char* const buf; | |
57 | }; | |
58 | ||
59 | struct out_slice_t { | |
60 | const std::size_t max_length; | |
61 | unsigned char* const buf; | |
62 | }; | |
63 | ||
64 | ceph::bufferptr secret; | |
65 | ||
66 | template <class BlockSizeT> | |
67 | CryptoKeyHandler(BlockSizeT) { | |
68 | static_assert(BlockSizeT::value <= MAX_BLOCK_SIZE); | |
69 | } | |
7c673cae FG |
70 | |
71 | virtual ~CryptoKeyHandler() {} | |
72 | ||
9f95a23c TL |
73 | virtual int encrypt(const ceph::buffer::list& in, |
74 | ceph::buffer::list& out, std::string *error) const = 0; | |
75 | virtual int decrypt(const ceph::buffer::list& in, | |
76 | ceph::buffer::list& out, std::string *error) const = 0; | |
11fdf7f2 TL |
77 | |
78 | // TODO: provide nullptr in the out::buf to get/estimate size requirements? | |
79 | // Or maybe dedicated methods? | |
80 | virtual std::size_t encrypt(const in_slice_t& in, | |
81 | const out_slice_t& out) const; | |
82 | virtual std::size_t decrypt(const in_slice_t& in, | |
83 | const out_slice_t& out) const; | |
84 | ||
85 | sha256_digest_t hmac_sha256(const ceph::bufferlist& in) const; | |
7c673cae FG |
86 | }; |
87 | ||
88 | /* | |
89 | * match encoding of struct ceph_secret | |
90 | */ | |
91 | class CryptoKey { | |
92 | protected: | |
93 | __u16 type; | |
94 | utime_t created; | |
9f95a23c | 95 | ceph::buffer::ptr secret; // must set this via set_secret()! |
7c673cae FG |
96 | |
97 | // cache a pointer to the implementation-specific key handler, so we | |
98 | // don't have to create it for every crypto operation. | |
11fdf7f2 | 99 | mutable std::shared_ptr<CryptoKeyHandler> ckh; |
7c673cae | 100 | |
9f95a23c | 101 | int _set_secret(int type, const ceph::buffer::ptr& s); |
7c673cae FG |
102 | |
103 | public: | |
104 | CryptoKey() : type(0) { } | |
9f95a23c | 105 | CryptoKey(int t, utime_t c, ceph::buffer::ptr& s) |
7c673cae FG |
106 | : created(c) { |
107 | _set_secret(t, s); | |
108 | } | |
109 | ~CryptoKey() { | |
110 | } | |
111 | ||
9f95a23c TL |
112 | void encode(ceph::buffer::list& bl) const; |
113 | void decode(ceph::buffer::list::const_iterator& bl); | |
7c673cae FG |
114 | |
115 | int get_type() const { return type; } | |
116 | utime_t get_created() const { return created; } | |
117 | void print(std::ostream& out) const; | |
118 | ||
9f95a23c TL |
119 | int set_secret(int type, const ceph::buffer::ptr& s, utime_t created); |
120 | const ceph::buffer::ptr& get_secret() { return secret; } | |
121 | const ceph::buffer::ptr& get_secret() const { return secret; } | |
7c673cae | 122 | |
11fdf7f2 TL |
123 | bool empty() const { return ckh.get() == nullptr; } |
124 | ||
9f95a23c TL |
125 | void encode_base64(std::string& s) const { |
126 | ceph::buffer::list bl; | |
7c673cae | 127 | encode(bl); |
9f95a23c | 128 | ceph::bufferlist e; |
7c673cae FG |
129 | bl.encode_base64(e); |
130 | e.append('\0'); | |
131 | s = e.c_str(); | |
132 | } | |
9f95a23c TL |
133 | std::string encode_base64() const { |
134 | std::string s; | |
7c673cae FG |
135 | encode_base64(s); |
136 | return s; | |
137 | } | |
9f95a23c TL |
138 | void decode_base64(const std::string& s) { |
139 | ceph::buffer::list e; | |
7c673cae | 140 | e.append(s); |
9f95a23c | 141 | ceph::buffer::list bl; |
7c673cae | 142 | bl.decode_base64(e); |
11fdf7f2 | 143 | auto p = std::cbegin(bl); |
7c673cae FG |
144 | decode(p); |
145 | } | |
146 | ||
9f95a23c TL |
147 | void encode_formatted(std::string label, ceph::Formatter *f, |
148 | ceph::buffer::list &bl); | |
149 | void encode_plaintext(ceph::buffer::list &bl); | |
7c673cae FG |
150 | |
151 | // -- | |
152 | int create(CephContext *cct, int type); | |
9f95a23c TL |
153 | int encrypt(CephContext *cct, const ceph::buffer::list& in, |
154 | ceph::buffer::list& out, | |
155 | std::string *error) const { | |
11fdf7f2 | 156 | ceph_assert(ckh); // Bad key? |
7c673cae FG |
157 | return ckh->encrypt(in, out, error); |
158 | } | |
9f95a23c TL |
159 | int decrypt(CephContext *cct, const ceph::buffer::list& in, |
160 | ceph::buffer::list& out, | |
161 | std::string *error) const { | |
11fdf7f2 | 162 | ceph_assert(ckh); // Bad key? |
7c673cae FG |
163 | return ckh->decrypt(in, out, error); |
164 | } | |
165 | ||
11fdf7f2 TL |
166 | using in_slice_t = CryptoKeyHandler::in_slice_t; |
167 | using out_slice_t = CryptoKeyHandler::out_slice_t; | |
168 | ||
169 | std::size_t encrypt(CephContext*, const in_slice_t& in, | |
170 | const out_slice_t& out) { | |
171 | ceph_assert(ckh); | |
172 | return ckh->encrypt(in, out); | |
173 | } | |
174 | std::size_t decrypt(CephContext*, const in_slice_t& in, | |
175 | const out_slice_t& out) { | |
176 | ceph_assert(ckh); | |
177 | return ckh->encrypt(in, out); | |
178 | } | |
179 | ||
9f95a23c | 180 | sha256_digest_t hmac_sha256(CephContext*, const ceph::buffer::list& in) { |
11fdf7f2 TL |
181 | ceph_assert(ckh); |
182 | return ckh->hmac_sha256(in); | |
183 | } | |
184 | ||
185 | static constexpr std::size_t get_max_outbuf_size(std::size_t want_size) { | |
186 | return want_size + CryptoKeyHandler::MAX_BLOCK_SIZE; | |
187 | } | |
188 | ||
7c673cae FG |
189 | void to_str(std::string& s) const; |
190 | }; | |
191 | WRITE_CLASS_ENCODER(CryptoKey) | |
192 | ||
9f95a23c | 193 | inline std::ostream& operator<<(std::ostream& out, const CryptoKey& k) |
7c673cae FG |
194 | { |
195 | k.print(out); | |
196 | return out; | |
197 | } | |
198 | ||
199 | ||
200 | /* | |
201 | * Driver for a particular algorithm | |
202 | * | |
203 | * To use these functions, you need to call ceph::crypto::init(), see | |
204 | * common/ceph_crypto.h. common_init_finish does this for you. | |
205 | */ | |
206 | class CryptoHandler { | |
207 | public: | |
208 | virtual ~CryptoHandler() {} | |
209 | virtual int get_type() const = 0; | |
9f95a23c TL |
210 | virtual int create(CryptoRandom *random, ceph::buffer::ptr& secret) = 0; |
211 | virtual int validate_secret(const ceph::buffer::ptr& secret) = 0; | |
212 | virtual CryptoKeyHandler *get_key_handler(const ceph::buffer::ptr& secret, | |
213 | std::string& error) = 0; | |
7c673cae FG |
214 | |
215 | static CryptoHandler *create(int type); | |
216 | }; | |
217 | ||
7c673cae FG |
218 | |
219 | #endif |