Bug Summary

File:src/lib/libssl/ssl_seclevel.c
Warning:line 227, column 9
Access to field 'cert' results in a dereference of a null pointer (loaded from variable 'ctx')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ssl_seclevel.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libssl/obj -resource-dir /usr/local/llvm16/lib/clang/16 -D LIBRESSL_INTERNAL -I /usr/src/lib/libssl -I /usr/src/lib/libssl/../libcrypto/hidden -I /usr/src/lib/libssl/../libcrypto/bio -I /usr/src/lib/libssl/hidden -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libssl/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/lib/libssl/ssl_seclevel.c
1/* $OpenBSD: ssl_seclevel.c,v 1.27 2022/11/26 16:08:56 tb Exp $ */
2/*
3 * Copyright (c) 2020-2022 Theo Buehler <tb@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <stddef.h>
19
20#include <openssl/asn1.h>
21#include <openssl/dh.h>
22#include <openssl/evp.h>
23#include <openssl/objects.h>
24#include <openssl/ossl_typ.h>
25#include <openssl/ssl.h>
26#include <openssl/tls1.h>
27#include <openssl/x509.h>
28#include <openssl/x509v3.h>
29
30#include "bytestring.h"
31#include "ssl_local.h"
32
33static int
34ssl_security_normalize_level(const SSL_CTX *ctx, const SSL *ssl, int *out_level)
35{
36 int security_level;
37
38 if (ctx != NULL((void *)0))
39 security_level = SSL_CTX_get_security_level(ctx);
40 else
41 security_level = SSL_get_security_level(ssl);
42
43 if (security_level < 0)
44 security_level = 0;
45 if (security_level > 5)
46 security_level = 5;
47
48 *out_level = security_level;
49
50 return 1;
51}
52
53static int
54ssl_security_level_to_minimum_bits(int security_level, int *out_minimum_bits)
55{
56 if (security_level < 0)
57 return 0;
58
59 if (security_level == 0)
60 *out_minimum_bits = 0;
61 else if (security_level == 1)
62 *out_minimum_bits = 80;
63 else if (security_level == 2)
64 *out_minimum_bits = 112;
65 else if (security_level == 3)
66 *out_minimum_bits = 128;
67 else if (security_level == 4)
68 *out_minimum_bits = 192;
69 else if (security_level >= 5)
70 *out_minimum_bits = 256;
71
72 return 1;
73}
74
75static int
76ssl_security_level_and_minimum_bits(const SSL_CTX *ctx, const SSL *ssl,
77 int *out_level, int *out_minimum_bits)
78{
79 int security_level = 0, minimum_bits = 0;
80
81 if (!ssl_security_normalize_level(ctx, ssl, &security_level))
82 return 0;
83 if (!ssl_security_level_to_minimum_bits(security_level, &minimum_bits))
84 return 0;
85
86 if (out_level != NULL((void *)0))
87 *out_level = security_level;
88 if (out_minimum_bits != NULL((void *)0))
89 *out_minimum_bits = minimum_bits;
90
91 return 1;
92}
93
94static int
95ssl_security_secop_cipher(const SSL_CTX *ctx, const SSL *ssl, int bits,
96 void *arg)
97{
98 const SSL_CIPHER *cipher = arg;
99 int security_level, minimum_bits;
100
101 if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
102 &minimum_bits))
103 return 0;
104
105 if (security_level <= 0)
106 return 1;
107
108 if (bits < minimum_bits)
109 return 0;
110
111 /* No unauthenticated ciphersuites. */
112 if (cipher->algorithm_auth & SSL_aNULL0x00000004L)
113 return 0;
114
115 if (cipher->algorithm_mac & SSL_MD50x00000001L)
116 return 0;
117
118 if (security_level <= 1)
119 return 1;
120
121 if (cipher->algorithm_enc & SSL_RC40x00000004L)
122 return 0;
123
124 if (security_level <= 2)
125 return 1;
126
127 /* Security level >= 3 requires a cipher with forward secrecy. */
128 if ((cipher->algorithm_mkey & (SSL_kDHE0x00000008L | SSL_kECDHE0x00000080L)) == 0 &&
129 cipher->algorithm_ssl != SSL_TLSV1_30x00000008L)
130 return 0;
131
132 if (security_level <= 3)
133 return 1;
134
135 if (cipher->algorithm_mac & SSL_SHA10x00000002L)
136 return 0;
137
138 return 1;
139}
140
141static int
142ssl_security_secop_version(const SSL_CTX *ctx, const SSL *ssl, int version)
143{
144 int min_version = TLS1_2_VERSION0x0303;
145 int security_level;
146
147 if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL((void *)0)))
148 return 0;
149
150 if (security_level < 4)
151 min_version = TLS1_1_VERSION0x0302;
152 if (security_level < 3)
153 min_version = TLS1_VERSION0x0301;
154
155 return ssl_tls_version(version) >= min_version;
156}
157
158static int
159ssl_security_secop_compression(const SSL_CTX *ctx, const SSL *ssl)
160{
161 return 0;
162}
163
164static int
165ssl_security_secop_tickets(const SSL_CTX *ctx, const SSL *ssl)
166{
167 int security_level;
168
169 if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL((void *)0)))
170 return 0;
171
172 return security_level < 3;
173}
174
175static int
176ssl_security_secop_tmp_dh(const SSL_CTX *ctx, const SSL *ssl, int bits)
177{
178 int security_level, minimum_bits;
179
180 if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
181 &minimum_bits))
182 return 0;
183
184 /* Disallow DHE keys weaker than 1024 bits even at security level 0. */
185 if (security_level <= 0 && bits < 80)
186 return 0;
187
188 return bits >= minimum_bits;
189}
190
191static int
192ssl_security_secop_default(const SSL_CTX *ctx, const SSL *ssl, int bits)
193{
194 int minimum_bits;
195
196 if (!ssl_security_level_and_minimum_bits(ctx, ssl, NULL((void *)0), &minimum_bits))
197 return 0;
198
199 return bits >= minimum_bits;
200}
201
202int
203ssl_security_default_cb(const SSL *ssl, const SSL_CTX *ctx, int secop, int bits,
204 int version, void *cipher, void *ex_data)
205{
206 switch (secop) {
207 case SSL_SECOP_CIPHER_SUPPORTED(1 | (1 << 16)):
208 case SSL_SECOP_CIPHER_SHARED(2 | (1 << 16)):
209 case SSL_SECOP_CIPHER_CHECK(3 | (1 << 16)):
210 return ssl_security_secop_cipher(ctx, ssl, bits, cipher);
211 case SSL_SECOP_VERSION(9 | 0):
212 return ssl_security_secop_version(ctx, ssl, version);
213 case SSL_SECOP_COMPRESSION(15 | 0):
214 return ssl_security_secop_compression(ctx, ssl);
215 case SSL_SECOP_TICKET(10 | 0):
216 return ssl_security_secop_tickets(ctx, ssl);
217 case SSL_SECOP_TMP_DH(7 | (3 << 16)):
218 return ssl_security_secop_tmp_dh(ctx, ssl, bits);
219 default:
220 return ssl_security_secop_default(ctx, ssl, bits);
221 }
222}
223
224static int
225ssl_ctx_security(const SSL_CTX *ctx, int secop, int bits, int nid, void *other)
226{
227 return ctx->cert->security_cb(NULL((void *)0), ctx, secop, bits, nid,
12
Access to field 'cert' results in a dereference of a null pointer (loaded from variable 'ctx')
228 other, ctx->cert->security_ex_data);
229}
230
231static int
232ssl_security(const SSL *ssl, int secop, int bits, int nid, void *other)
233{
234 return ssl->cert->security_cb(ssl, NULL((void *)0), secop, bits, nid, other,
235 ssl->cert->security_ex_data);
236}
237
238int
239ssl_security_sigalg_check(const SSL *ssl, const EVP_PKEY *pkey)
240{
241 int bits;
242
243 bits = EVP_PKEY_security_bits(pkey);
244
245 return ssl_security(ssl, SSL_SECOP_SIGALG_CHECK(13 | (5 << 16)), bits, 0, NULL((void *)0));
246}
247
248int
249ssl_security_tickets(const SSL *ssl)
250{
251 return ssl_security(ssl, SSL_SECOP_TICKET(10 | 0), 0, 0, NULL((void *)0));
252}
253
254int
255ssl_security_version(const SSL *ssl, int version)
256{
257 return ssl_security(ssl, SSL_SECOP_VERSION(9 | 0), 0, version, NULL((void *)0));
258}
259
260static int
261ssl_security_cipher(const SSL *ssl, SSL_CIPHER *cipher, int secop)
262{
263 return ssl_security(ssl, secop, cipher->strength_bits, 0, cipher);
264}
265
266int
267ssl_security_cipher_check(const SSL *ssl, SSL_CIPHER *cipher)
268{
269 return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_CHECK(3 | (1 << 16)));
270}
271
272int
273ssl_security_shared_cipher(const SSL *ssl, SSL_CIPHER *cipher)
274{
275 return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SHARED(2 | (1 << 16)));
276}
277
278int
279ssl_security_supported_cipher(const SSL *ssl, SSL_CIPHER *cipher)
280{
281 return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SUPPORTED(1 | (1 << 16)));
282}
283
284int
285ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh)
286{
287 int bits;
288
289 bits = DH_security_bits(dh);
290
291 return ssl_ctx_security(ctx, SSL_SECOP_TMP_DH(7 | (3 << 16)), bits, 0, dh);
292}
293
294int
295ssl_security_dh(const SSL *ssl, DH *dh)
296{
297 int bits;
298
299 bits = DH_security_bits(dh);
300
301 return ssl_security(ssl, SSL_SECOP_TMP_DH(7 | (3 << 16)), bits, 0, dh);
302}
303
304static int
305ssl_cert_pubkey_security_bits(const X509 *x509)
306{
307 EVP_PKEY *pkey;
308
309 if ((pkey = X509_get0_pubkey(x509)) == NULL((void *)0))
310 return -1;
311
312 /*
313 * XXX: DSA_security_bits() returns -1 on keys without parameters and
314 * makes the default security callback fail.
315 */
316
317 return EVP_PKEY_security_bits(pkey);
318}
319
320static int
321ssl_security_cert_key(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
322{
323 int security_bits;
324
325 security_bits = ssl_cert_pubkey_security_bits(x509);
326
327 if (ssl != NULL((void *)0))
8
Assuming 'ssl' is equal to NULL
9
Taking false branch
328 return ssl_security(ssl, secop, security_bits, 0, x509);
329
330 return ssl_ctx_security(ctx, secop, security_bits, 0, x509);
10
Passing null pointer value via 1st parameter 'ctx'
11
Calling 'ssl_ctx_security'
331}
332
333static int
334ssl_cert_signature_md_nid(X509 *x509)
335{
336 int md_nid, signature_nid;
337
338 if ((signature_nid = X509_get_signature_nid(x509)) == NID_undef0)
339 return NID_undef0;
340
341 if (!OBJ_find_sigid_algs(signature_nid, &md_nid, NULL((void *)0)))
342 return NID_undef0;
343
344 return md_nid;
345}
346
347static int
348ssl_cert_md_nid_security_bits(int md_nid)
349{
350 const EVP_MD *md;
351
352 if (md_nid == NID_undef0)
353 return -1;
354
355 if ((md = EVP_get_digestbynid(md_nid)EVP_get_digestbyname(OBJ_nid2sn(md_nid))) == NULL((void *)0))
356 return -1;
357
358 /* Assume 4 bits of collision resistance for each hash octet. */
359 return EVP_MD_size(md) * 4;
360}
361
362static int
363ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
364{
365 int md_nid, security_bits;
366
367 /* Don't check signature if self signed. */
368 if ((X509_get_extension_flags(x509) & EXFLAG_SS0x2000) != 0)
369 return 1;
370
371 md_nid = ssl_cert_signature_md_nid(x509);
372 security_bits = ssl_cert_md_nid_security_bits(md_nid);
373
374 if (ssl != NULL((void *)0))
375 return ssl_security(ssl, secop, security_bits, md_nid, x509);
376
377 return ssl_ctx_security(ctx, secop, security_bits, md_nid, x509);
378}
379
380int
381ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509,
382 int is_ee, int *out_error)
383{
384 int key_error, operation;
385
386 *out_error = 0;
387
388 if (is_ee
4.1
'is_ee' is 1
) {
5
Taking true branch
389 operation = SSL_SECOP_EE_KEY(16 | (6 << 16));
390 key_error = SSL_R_EE_KEY_TOO_SMALL399;
391 } else {
392 operation = SSL_SECOP_CA_KEY(17 | (6 << 16));
393 key_error = SSL_R_CA_KEY_TOO_SMALL397;
394 }
395
396 if (!ssl_security_cert_key(ctx, ssl, x509, operation)) {
6
Passing null pointer value via 1st parameter 'ctx'
7
Calling 'ssl_security_cert_key'
397 *out_error = key_error;
398 return 0;
399 }
400
401 if (!ssl_security_cert_sig(ctx, ssl, x509, SSL_SECOP_CA_MD(18 | (6 << 16)))) {
402 *out_error = SSL_R_CA_MD_TOO_WEAK398;
403 return 0;
404 }
405
406 return 1;
407}
408
409/*
410 * Check security of a chain. If |sk| includes the end entity certificate
411 * then |x509| must be NULL.
412 */
413int
414ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509)struct stack_st_X509 *sk, X509 *x509,
415 int *out_error)
416{
417 int start_idx = 0;
418 int is_ee;
419 int i;
420
421 if (x509 == NULL((void *)0)) {
1
Assuming 'x509' is not equal to NULL
2
Taking false branch
422 x509 = sk_X509_value(sk, 0)((X509 *)sk_value(((_STACK*) (1 ? (sk) : (struct stack_st_X509
*)0)), (0)))
;
423 start_idx = 1;
424 }
425
426 is_ee = 1;
427 if (!ssl_security_cert(NULL((void *)0), ssl, x509, is_ee, out_error))
3
Passing null pointer value via 1st parameter 'ctx'
4
Calling 'ssl_security_cert'
428 return 0;
429
430 is_ee = 0;
431 for (i = start_idx; i < sk_X509_num(sk)sk_num(((_STACK*) (1 ? (sk) : (struct stack_st_X509*)0))); i++) {
432 x509 = sk_X509_value(sk, i)((X509 *)sk_value(((_STACK*) (1 ? (sk) : (struct stack_st_X509
*)0)), (i)))
;
433
434 if (!ssl_security_cert(NULL((void *)0), ssl, x509, is_ee, out_error))
435 return 0;
436 }
437
438 return 1;
439}
440
441static int
442ssl_security_group(const SSL *ssl, uint16_t group_id, int secop)
443{
444 CBB cbb;
445 int bits, nid;
446 uint8_t group[2];
447
448 if (!tls1_ec_group_id2bits(group_id, &bits))
449 return 0;
450 if (!tls1_ec_group_id2nid(group_id, &nid))
451 return 0;
452
453 if (!CBB_init_fixed(&cbb, group, sizeof(group)))
454 return 0;
455 if (!CBB_add_u16(&cbb, group_id))
456 return 0;
457 if (!CBB_finish(&cbb, NULL((void *)0), NULL((void *)0)))
458 return 0;
459
460 return ssl_security(ssl, secop, bits, nid, group);
461}
462
463int
464ssl_security_shared_group(const SSL *ssl, uint16_t group_id)
465{
466 return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SHARED(5 | (2 << 16)));
467}
468
469int
470ssl_security_supported_group(const SSL *ssl, uint16_t group_id)
471{
472 return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SUPPORTED(4 | (2 << 16)));
473}