1 /* Copyright (c) 2024, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/ssl.h>
16
17 #include <assert.h>
18
19 #include <openssl/span.h>
20
21 #include "internal.h"
22 #include "../crypto/internal.h"
23
24
25 BSSL_NAMESPACE_BEGIN
26
27 // new_leafless_chain returns a fresh stack of buffers set to {nullptr}.
new_leafless_chain(void)28 static UniquePtr<STACK_OF(CRYPTO_BUFFER)> new_leafless_chain(void) {
29 UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain(sk_CRYPTO_BUFFER_new_null());
30 if (!chain ||
31 !sk_CRYPTO_BUFFER_push(chain.get(), nullptr)) {
32 return nullptr;
33 }
34
35 return chain;
36 }
37
ssl_get_credential_list(SSL_HANDSHAKE * hs,Array<SSL_CREDENTIAL * > * out)38 bool ssl_get_credential_list(SSL_HANDSHAKE *hs, Array<SSL_CREDENTIAL *> *out) {
39 CERT *cert = hs->config->cert.get();
40 // Finish filling in the default credential if needed.
41 if (!cert->x509_method->ssl_auto_chain_if_needed(hs)) {
42 return false;
43 }
44
45 size_t num_creds = cert->credentials.size();
46 bool include_default = cert->default_credential->IsComplete();
47 if (include_default) {
48 num_creds++;
49 }
50
51 if (!out->Init(num_creds)) {
52 return false;
53 }
54
55 for (size_t i = 0; i < cert->credentials.size(); i++) {
56 (*out)[i] = cert->credentials[i].get();
57 }
58 if (include_default) {
59 (*out)[num_creds - 1] = cert->default_credential.get();
60 }
61 return true;
62 }
63
64 BSSL_NAMESPACE_END
65
66 using namespace bssl;
67
68 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
69
ssl_credential_st(SSLCredentialType type_arg)70 ssl_credential_st::ssl_credential_st(SSLCredentialType type_arg)
71 : RefCounted(CheckSubClass()), type(type_arg) {
72 CRYPTO_new_ex_data(&ex_data);
73 }
74
~ssl_credential_st()75 ssl_credential_st::~ssl_credential_st() {
76 CRYPTO_free_ex_data(&g_ex_data_class, this, &ex_data);
77 }
78
buffer_up_ref(const CRYPTO_BUFFER * buffer)79 static CRYPTO_BUFFER *buffer_up_ref(const CRYPTO_BUFFER *buffer) {
80 CRYPTO_BUFFER_up_ref(const_cast<CRYPTO_BUFFER *>(buffer));
81 return const_cast<CRYPTO_BUFFER *>(buffer);
82 }
83
Dup() const84 UniquePtr<SSL_CREDENTIAL> ssl_credential_st::Dup() const {
85 assert(type == SSLCredentialType::kX509);
86 UniquePtr<SSL_CREDENTIAL> ret = MakeUnique<SSL_CREDENTIAL>(type);
87 if (ret == nullptr) {
88 return nullptr;
89 }
90
91 ret->pubkey = UpRef(pubkey);
92 ret->privkey = UpRef(privkey);
93 ret->key_method = key_method;
94 if (!ret->sigalgs.CopyFrom(sigalgs)) {
95 return nullptr;
96 }
97
98 if (chain) {
99 ret->chain.reset(sk_CRYPTO_BUFFER_deep_copy(chain.get(), buffer_up_ref,
100 CRYPTO_BUFFER_free));
101 if (!ret->chain) {
102 return nullptr;
103 }
104 }
105
106 ret->dc = UpRef(dc);
107 ret->signed_cert_timestamp_list = UpRef(signed_cert_timestamp_list);
108 ret->ocsp_response = UpRef(ocsp_response);
109 ret->dc_algorithm = dc_algorithm;
110 return ret;
111 }
112
ClearCertAndKey()113 void ssl_credential_st::ClearCertAndKey() {
114 pubkey = nullptr;
115 privkey = nullptr;
116 key_method = nullptr;
117 chain = nullptr;
118 }
119
UsesX509() const120 bool ssl_credential_st::UsesX509() const {
121 // Currently, all credential types use X.509. However, we may add other
122 // certificate types in the future. Add the checks in the setters now, so we
123 // don't forget.
124 return true;
125 }
126
UsesPrivateKey() const127 bool ssl_credential_st::UsesPrivateKey() const {
128 // Currently, all credential types use private keys. However, we may add PSK
129 return true;
130 }
131
IsComplete() const132 bool ssl_credential_st::IsComplete() const {
133 // APIs like |SSL_use_certificate| and |SSL_set1_chain| configure the leaf and
134 // other certificates separately. It is possible for |chain| have a null leaf.
135 if (UsesX509() && (sk_CRYPTO_BUFFER_num(chain.get()) == 0 ||
136 sk_CRYPTO_BUFFER_value(chain.get(), 0) == nullptr)) {
137 return false;
138 }
139 // We must have successfully extracted a public key from the certificate,
140 // delegated credential, etc.
141 if (UsesPrivateKey() && pubkey == nullptr) {
142 return false;
143 }
144 if (UsesPrivateKey() && privkey == nullptr && key_method == nullptr) {
145 return false;
146 }
147 if (type == SSLCredentialType::kDelegated && dc == nullptr) {
148 return false;
149 }
150 return true;
151 }
152
SetLeafCert(UniquePtr<CRYPTO_BUFFER> leaf,bool discard_key_on_mismatch)153 bool ssl_credential_st::SetLeafCert(UniquePtr<CRYPTO_BUFFER> leaf,
154 bool discard_key_on_mismatch) {
155 if (!UsesX509()) {
156 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
157 return false;
158 }
159
160 const bool private_key_matches_leaf = type != SSLCredentialType::kDelegated;
161
162 CBS cbs;
163 CRYPTO_BUFFER_init_CBS(leaf.get(), &cbs);
164 UniquePtr<EVP_PKEY> new_pubkey = ssl_cert_parse_pubkey(&cbs);
165 if (new_pubkey == nullptr) {
166 return false;
167 }
168
169 if (!ssl_is_key_type_supported(EVP_PKEY_id(new_pubkey.get()))) {
170 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
171 return false;
172 }
173
174 // An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
175 // certificates, so sanity-check the key usage extension.
176 if (EVP_PKEY_id(new_pubkey.get()) == EVP_PKEY_EC &&
177 !ssl_cert_check_key_usage(&cbs, key_usage_digital_signature)) {
178 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
179 return false;
180 }
181
182 if (private_key_matches_leaf && privkey != nullptr &&
183 !ssl_compare_public_and_private_key(new_pubkey.get(), privkey.get())) {
184 if (!discard_key_on_mismatch) {
185 return false;
186 }
187 ERR_clear_error();
188 privkey = nullptr;
189 }
190
191 if (chain == nullptr) {
192 chain = new_leafless_chain();
193 if (chain == nullptr) {
194 return false;
195 }
196 }
197
198 CRYPTO_BUFFER_free(sk_CRYPTO_BUFFER_value(chain.get(), 0));
199 sk_CRYPTO_BUFFER_set(chain.get(), 0, leaf.release());
200 if (private_key_matches_leaf) {
201 pubkey = std::move(new_pubkey);
202 }
203 return true;
204 }
205
ClearIntermediateCerts()206 void ssl_credential_st::ClearIntermediateCerts() {
207 if (chain == nullptr) {
208 return;
209 }
210
211 while (sk_CRYPTO_BUFFER_num(chain.get()) > 1) {
212 CRYPTO_BUFFER_free(sk_CRYPTO_BUFFER_pop(chain.get()));
213 }
214 }
215
AppendIntermediateCert(UniquePtr<CRYPTO_BUFFER> cert)216 bool ssl_credential_st::AppendIntermediateCert(UniquePtr<CRYPTO_BUFFER> cert) {
217 if (!UsesX509()) {
218 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
219 return false;
220 }
221
222 if (chain == nullptr) {
223 chain = new_leafless_chain();
224 if (chain == nullptr) {
225 return false;
226 }
227 }
228
229 return PushToStack(chain.get(), std::move(cert));
230 }
231
SSL_CREDENTIAL_new_x509(void)232 SSL_CREDENTIAL *SSL_CREDENTIAL_new_x509(void) {
233 return New<SSL_CREDENTIAL>(SSLCredentialType::kX509);
234 }
235
SSL_CREDENTIAL_new_delegated(void)236 SSL_CREDENTIAL *SSL_CREDENTIAL_new_delegated(void) {
237 return New<SSL_CREDENTIAL>(SSLCredentialType::kDelegated);
238 }
239
SSL_CREDENTIAL_up_ref(SSL_CREDENTIAL * cred)240 void SSL_CREDENTIAL_up_ref(SSL_CREDENTIAL *cred) { cred->UpRefInternal(); }
241
SSL_CREDENTIAL_free(SSL_CREDENTIAL * cred)242 void SSL_CREDENTIAL_free(SSL_CREDENTIAL *cred) {
243 if (cred != nullptr) {
244 cred->DecRefInternal();
245 }
246 }
247
SSL_CREDENTIAL_set1_private_key(SSL_CREDENTIAL * cred,EVP_PKEY * key)248 int SSL_CREDENTIAL_set1_private_key(SSL_CREDENTIAL *cred, EVP_PKEY *key) {
249 if (!cred->UsesPrivateKey()) {
250 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
251 return 0;
252 }
253
254 // If the public half has been configured, check |key| matches. |pubkey| will
255 // have been extracted from the certificate, delegated credential, etc.
256 if (cred->pubkey != nullptr &&
257 !ssl_compare_public_and_private_key(cred->pubkey.get(), key)) {
258 return false;
259 }
260
261 cred->privkey = UpRef(key);
262 cred->key_method = nullptr;
263 return 1;
264 }
265
SSL_CREDENTIAL_set_private_key_method(SSL_CREDENTIAL * cred,const SSL_PRIVATE_KEY_METHOD * key_method)266 int SSL_CREDENTIAL_set_private_key_method(
267 SSL_CREDENTIAL *cred, const SSL_PRIVATE_KEY_METHOD *key_method) {
268 if (!cred->UsesPrivateKey()) {
269 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
270 return 0;
271 }
272
273 cred->privkey = nullptr;
274 cred->key_method = key_method;
275 return 1;
276 }
277
SSL_CREDENTIAL_set1_cert_chain(SSL_CREDENTIAL * cred,CRYPTO_BUFFER * const * certs,size_t num_certs)278 int SSL_CREDENTIAL_set1_cert_chain(SSL_CREDENTIAL *cred,
279 CRYPTO_BUFFER *const *certs,
280 size_t num_certs) {
281 if (!cred->UsesX509() || num_certs == 0) {
282 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
283 return 0;
284 }
285
286 if (!cred->SetLeafCert(UpRef(certs[0]), /*discard_key_on_mismatch=*/false)) {
287 return 0;
288 }
289
290 cred->ClearIntermediateCerts();
291 for (size_t i = 1; i < num_certs; i++) {
292 if (!cred->AppendIntermediateCert(UpRef(certs[i]))) {
293 return 0;
294 }
295 }
296
297 return 1;
298 }
299
SSL_CREDENTIAL_set1_delegated_credential(SSL_CREDENTIAL * cred,CRYPTO_BUFFER * dc)300 int SSL_CREDENTIAL_set1_delegated_credential(
301 SSL_CREDENTIAL *cred, CRYPTO_BUFFER *dc) {
302 if (cred->type != SSLCredentialType::kDelegated) {
303 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
304 return 0;
305 }
306
307 // Parse the delegated credential to check for validity, and extract a few
308 // fields from it. See RFC 9345, section 4.
309 CBS cbs, spki, sig;
310 uint32_t valid_time;
311 uint16_t dc_cert_verify_algorithm, algorithm;
312 CRYPTO_BUFFER_init_CBS(dc, &cbs);
313 if (!CBS_get_u32(&cbs, &valid_time) ||
314 !CBS_get_u16(&cbs, &dc_cert_verify_algorithm) ||
315 !CBS_get_u24_length_prefixed(&cbs, &spki) ||
316 !CBS_get_u16(&cbs, &algorithm) ||
317 !CBS_get_u16_length_prefixed(&cbs, &sig) || //
318 CBS_len(&sig) == 0 || //
319 CBS_len(&cbs) != 0) {
320 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
321 return 0;
322 }
323
324 // RFC 9345 forbids algorithms that use the rsaEncryption OID. As the
325 // RSASSA-PSS OID is unusably complicated, this effectively means we will not
326 // support RSA delegated credentials.
327 if (SSL_get_signature_algorithm_key_type(dc_cert_verify_algorithm) ==
328 EVP_PKEY_RSA) {
329 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
330 return 0;
331 }
332
333 UniquePtr<EVP_PKEY> pubkey(EVP_parse_public_key(&spki));
334 if (pubkey == nullptr || CBS_len(&spki) != 0) {
335 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
336 return 0;
337 }
338
339 if (!cred->sigalgs.CopyFrom(MakeConstSpan(&dc_cert_verify_algorithm, 1))) {
340 return 0;
341 }
342
343 if (cred->privkey != nullptr &&
344 !ssl_compare_public_and_private_key(pubkey.get(), cred->privkey.get())) {
345 return 0;
346 }
347
348 cred->dc = UpRef(dc);
349 cred->pubkey = std::move(pubkey);
350 cred->dc_algorithm = algorithm;
351 return 1;
352 }
353
SSL_CREDENTIAL_set1_ocsp_response(SSL_CREDENTIAL * cred,CRYPTO_BUFFER * ocsp)354 int SSL_CREDENTIAL_set1_ocsp_response(SSL_CREDENTIAL *cred,
355 CRYPTO_BUFFER *ocsp) {
356 if (!cred->UsesX509()) {
357 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
358 return 0;
359 }
360
361 cred->ocsp_response = UpRef(ocsp);
362 return 1;
363 }
364
SSL_CREDENTIAL_set1_signed_cert_timestamp_list(SSL_CREDENTIAL * cred,CRYPTO_BUFFER * sct_list)365 int SSL_CREDENTIAL_set1_signed_cert_timestamp_list(SSL_CREDENTIAL *cred,
366 CRYPTO_BUFFER *sct_list) {
367 if (!cred->UsesX509()) {
368 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
369 return 0;
370 }
371
372 CBS cbs;
373 CRYPTO_BUFFER_init_CBS(sct_list, &cbs);
374 if (!ssl_is_sct_list_valid(&cbs)) {
375 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SCT_LIST);
376 return 0;
377 }
378
379 cred->signed_cert_timestamp_list = UpRef(sct_list);
380 return 1;
381 }
382
SSL_CTX_add1_credential(SSL_CTX * ctx,SSL_CREDENTIAL * cred)383 int SSL_CTX_add1_credential(SSL_CTX *ctx, SSL_CREDENTIAL *cred) {
384 if (!cred->IsComplete()) {
385 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
386 return 0;
387 }
388 return ctx->cert->credentials.Push(UpRef(cred));
389 }
390
SSL_add1_credential(SSL * ssl,SSL_CREDENTIAL * cred)391 int SSL_add1_credential(SSL *ssl, SSL_CREDENTIAL *cred) {
392 if (ssl->config == nullptr) {
393 return 0;
394 }
395
396 if (!cred->IsComplete()) {
397 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
398 return 0;
399 }
400 return ssl->config->cert->credentials.Push(UpRef(cred));
401 }
402
SSL_get0_selected_credential(const SSL * ssl)403 const SSL_CREDENTIAL *SSL_get0_selected_credential(const SSL *ssl) {
404 if (ssl->s3->hs == nullptr) {
405 return nullptr;
406 }
407 return ssl->s3->hs->credential.get();
408 }
409
SSL_CREDENTIAL_get_ex_new_index(long argl,void * argp,CRYPTO_EX_unused * unused,CRYPTO_EX_dup * dup_unused,CRYPTO_EX_free * free_func)410 int SSL_CREDENTIAL_get_ex_new_index(long argl, void *argp,
411 CRYPTO_EX_unused *unused,
412 CRYPTO_EX_dup *dup_unused,
413 CRYPTO_EX_free *free_func) {
414 return CRYPTO_get_ex_new_index_ex(&g_ex_data_class, argl, argp, free_func);
415 }
416
SSL_CREDENTIAL_set_ex_data(SSL_CREDENTIAL * cred,int idx,void * arg)417 int SSL_CREDENTIAL_set_ex_data(SSL_CREDENTIAL *cred, int idx, void *arg) {
418 return CRYPTO_set_ex_data(&cred->ex_data, idx, arg);
419 }
420
SSL_CREDENTIAL_get_ex_data(const SSL_CREDENTIAL * cred,int idx)421 void *SSL_CREDENTIAL_get_ex_data(const SSL_CREDENTIAL *cred, int idx) {
422 return CRYPTO_get_ex_data(&cred->ex_data, idx);
423 }
424