xref: /openbsd-src/lib/libssl/ssl_seclevel.c (revision 942444cc7c5998c174b1d5168c17b8b0c38602a8)
1*942444ccStb /*	$OpenBSD: ssl_seclevel.c,v 1.30 2025/01/18 10:52:09 tb Exp $ */
26638350cStb /*
3ae2ee916Stb  * Copyright (c) 2020-2022 Theo Buehler <tb@openbsd.org>
46638350cStb  *
56638350cStb  * Permission to use, copy, modify, and distribute this software for any
66638350cStb  * purpose with or without fee is hereby granted, provided that the above
76638350cStb  * copyright notice and this permission notice appear in all copies.
86638350cStb  *
96638350cStb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
106638350cStb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
116638350cStb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
126638350cStb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
136638350cStb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
146638350cStb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
156638350cStb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
166638350cStb  */
176638350cStb 
186638350cStb #include <stddef.h>
196638350cStb 
205f8716e2Stb #include <openssl/asn1.h>
212c1036d8Stb #include <openssl/dh.h>
225f8716e2Stb #include <openssl/evp.h>
235f8716e2Stb #include <openssl/objects.h>
246638350cStb #include <openssl/ossl_typ.h>
256638350cStb #include <openssl/ssl.h>
266638350cStb #include <openssl/tls1.h>
275f8716e2Stb #include <openssl/x509.h>
28e9f75676Stb #include <openssl/x509v3.h>
296638350cStb 
3013053e69Stb #include "bytestring.h"
31c9675a23Stb #include "ssl_local.h"
326638350cStb 
336638350cStb static int
346638350cStb ssl_security_normalize_level(const SSL_CTX *ctx, const SSL *ssl, int *out_level)
356638350cStb {
366638350cStb 	int security_level;
376638350cStb 
386638350cStb 	if (ctx != NULL)
396638350cStb 		security_level = SSL_CTX_get_security_level(ctx);
406638350cStb 	else
416638350cStb 		security_level = SSL_get_security_level(ssl);
426638350cStb 
436638350cStb 	if (security_level < 0)
446638350cStb 		security_level = 0;
456638350cStb 	if (security_level > 5)
466638350cStb 		security_level = 5;
476638350cStb 
486638350cStb 	*out_level = security_level;
496638350cStb 
506638350cStb 	return 1;
516638350cStb }
526638350cStb 
536638350cStb static int
546638350cStb ssl_security_level_to_minimum_bits(int security_level, int *out_minimum_bits)
556638350cStb {
566638350cStb 	if (security_level < 0)
576638350cStb 		return 0;
586638350cStb 
596638350cStb 	if (security_level == 0)
606638350cStb 		*out_minimum_bits = 0;
616638350cStb 	else if (security_level == 1)
626638350cStb 		*out_minimum_bits = 80;
636638350cStb 	else if (security_level == 2)
646638350cStb 		*out_minimum_bits = 112;
656638350cStb 	else if (security_level == 3)
666638350cStb 		*out_minimum_bits = 128;
676638350cStb 	else if (security_level == 4)
686638350cStb 		*out_minimum_bits = 192;
696638350cStb 	else if (security_level >= 5)
706638350cStb 		*out_minimum_bits = 256;
716638350cStb 
726638350cStb 	return 1;
736638350cStb }
746638350cStb 
756638350cStb static int
766638350cStb ssl_security_level_and_minimum_bits(const SSL_CTX *ctx, const SSL *ssl,
776638350cStb     int *out_level, int *out_minimum_bits)
786638350cStb {
796638350cStb 	int security_level = 0, minimum_bits = 0;
806638350cStb 
816638350cStb 	if (!ssl_security_normalize_level(ctx, ssl, &security_level))
826638350cStb 		return 0;
836638350cStb 	if (!ssl_security_level_to_minimum_bits(security_level, &minimum_bits))
846638350cStb 		return 0;
856638350cStb 
866638350cStb 	if (out_level != NULL)
876638350cStb 		*out_level = security_level;
886638350cStb 	if (out_minimum_bits != NULL)
896638350cStb 		*out_minimum_bits = minimum_bits;
906638350cStb 
916638350cStb 	return 1;
926638350cStb }
936638350cStb 
946638350cStb static int
956638350cStb ssl_security_secop_cipher(const SSL_CTX *ctx, const SSL *ssl, int bits,
966638350cStb     void *arg)
976638350cStb {
986638350cStb 	const SSL_CIPHER *cipher = arg;
996638350cStb 	int security_level, minimum_bits;
1006638350cStb 
1016638350cStb 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
1026638350cStb 	    &minimum_bits))
1036638350cStb 		return 0;
1046638350cStb 
1056638350cStb 	if (security_level <= 0)
1066638350cStb 		return 1;
1076638350cStb 
1086638350cStb 	if (bits < minimum_bits)
1096638350cStb 		return 0;
1106638350cStb 
11171ad7195Stb 	/* No unauthenticated ciphersuites. */
1126638350cStb 	if (cipher->algorithm_auth & SSL_aNULL)
1136638350cStb 		return 0;
1146638350cStb 
115a042a42dStb 	if (cipher->algorithm_mac & SSL_MD5)
116a042a42dStb 		return 0;
117a042a42dStb 
1186638350cStb 	if (security_level <= 1)
1196638350cStb 		return 1;
1206638350cStb 
121a042a42dStb 	if (cipher->algorithm_enc & SSL_RC4)
1226638350cStb 		return 0;
1236638350cStb 
1246638350cStb 	if (security_level <= 2)
1256638350cStb 		return 1;
1266638350cStb 
127a1ab956aStb 	/* Security level >= 3 requires a cipher with forward secrecy. */
128a1ab956aStb 	if ((cipher->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) == 0 &&
129a1ab956aStb 	    cipher->algorithm_ssl != SSL_TLSV1_3)
1306638350cStb 		return 0;
1316638350cStb 
132a042a42dStb 	if (security_level <= 3)
133a042a42dStb 		return 1;
134a042a42dStb 
135a042a42dStb 	if (cipher->algorithm_mac & SSL_SHA1)
136a042a42dStb 		return 0;
137a042a42dStb 
1386638350cStb 	return 1;
1396638350cStb }
1406638350cStb 
1416638350cStb static int
1426638350cStb ssl_security_secop_version(const SSL_CTX *ctx, const SSL *ssl, int version)
1436638350cStb {
1446638350cStb 	int min_version = TLS1_2_VERSION;
1456638350cStb 	int security_level;
1466638350cStb 
1476638350cStb 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL))
1486638350cStb 		return 0;
1496638350cStb 
1506638350cStb 	if (security_level < 4)
1516638350cStb 		min_version = TLS1_1_VERSION;
1526638350cStb 	if (security_level < 3)
1536638350cStb 		min_version = TLS1_VERSION;
1546638350cStb 
1556638350cStb 	return ssl_tls_version(version) >= min_version;
1566638350cStb }
1576638350cStb 
1586638350cStb static int
1596638350cStb ssl_security_secop_compression(const SSL_CTX *ctx, const SSL *ssl)
1606638350cStb {
1616638350cStb 	return 0;
1626638350cStb }
1636638350cStb 
1646638350cStb static int
1656638350cStb ssl_security_secop_tickets(const SSL_CTX *ctx, const SSL *ssl)
1666638350cStb {
1676638350cStb 	int security_level;
1686638350cStb 
1696638350cStb 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL))
1706638350cStb 		return 0;
1716638350cStb 
1726638350cStb 	return security_level < 3;
1736638350cStb }
1746638350cStb 
1756638350cStb static int
17697a397f3Stb ssl_security_secop_tmp_dh(const SSL_CTX *ctx, const SSL *ssl, int bits)
17797a397f3Stb {
17897a397f3Stb 	int security_level, minimum_bits;
17997a397f3Stb 
18097a397f3Stb 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
18197a397f3Stb 	    &minimum_bits))
18297a397f3Stb 		return 0;
18397a397f3Stb 
18497a397f3Stb 	/* Disallow DHE keys weaker than 1024 bits even at security level 0. */
18597a397f3Stb 	if (security_level <= 0 && bits < 80)
18697a397f3Stb 		return 0;
18797a397f3Stb 
18897a397f3Stb 	return bits >= minimum_bits;
18997a397f3Stb }
19097a397f3Stb 
19197a397f3Stb static int
1926638350cStb ssl_security_secop_default(const SSL_CTX *ctx, const SSL *ssl, int bits)
1936638350cStb {
1946638350cStb 	int minimum_bits;
1956638350cStb 
1966638350cStb 	if (!ssl_security_level_and_minimum_bits(ctx, ssl, NULL, &minimum_bits))
1976638350cStb 		return 0;
1986638350cStb 
1996638350cStb 	return bits >= minimum_bits;
2006638350cStb }
2016638350cStb 
2026638350cStb int
20337d1243cStb ssl_security_default_cb(const SSL *ssl, const SSL_CTX *ctx, int secop, int bits,
2046638350cStb     int version, void *cipher, void *ex_data)
2056638350cStb {
20637d1243cStb 	switch (secop) {
2076638350cStb 	case SSL_SECOP_CIPHER_SUPPORTED:
2086638350cStb 	case SSL_SECOP_CIPHER_SHARED:
2096638350cStb 	case SSL_SECOP_CIPHER_CHECK:
2106638350cStb 		return ssl_security_secop_cipher(ctx, ssl, bits, cipher);
2116638350cStb 	case SSL_SECOP_VERSION:
2126638350cStb 		return ssl_security_secop_version(ctx, ssl, version);
2136638350cStb 	case SSL_SECOP_COMPRESSION:
2146638350cStb 		return ssl_security_secop_compression(ctx, ssl);
2156638350cStb 	case SSL_SECOP_TICKET:
2166638350cStb 		return ssl_security_secop_tickets(ctx, ssl);
21797a397f3Stb 	case SSL_SECOP_TMP_DH:
21897a397f3Stb 		return ssl_security_secop_tmp_dh(ctx, ssl, bits);
2196638350cStb 	default:
2206638350cStb 		return ssl_security_secop_default(ctx, ssl, bits);
2216638350cStb 	}
2226638350cStb }
2236638350cStb 
224bf22d29dStb static int
22537d1243cStb ssl_ctx_security(const SSL_CTX *ctx, int secop, int bits, int nid, void *other)
2267ca355bcStb {
2276f7f653bSjsing 	return ctx->cert->security_cb(NULL, ctx, secop, bits, nid,
2286f7f653bSjsing 	    other, ctx->cert->security_ex_data);
2297ca355bcStb }
2307ca355bcStb 
2311fd41f50Stb static int
23237d1243cStb ssl_security(const SSL *ssl, int secop, int bits, int nid, void *other)
2337ca355bcStb {
23437d1243cStb 	return ssl->cert->security_cb(ssl, NULL, secop, bits, nid, other,
2357ca355bcStb 	    ssl->cert->security_ex_data);
2367ca355bcStb }
2372c1036d8Stb 
2382c1036d8Stb int
2391fd41f50Stb ssl_security_sigalg_check(const SSL *ssl, const EVP_PKEY *pkey)
2401fd41f50Stb {
24168d7a0a5Stb 	int bits;
24268d7a0a5Stb 
24368d7a0a5Stb 	bits = EVP_PKEY_security_bits(pkey);
24468d7a0a5Stb 
24568d7a0a5Stb 	return ssl_security(ssl, SSL_SECOP_SIGALG_CHECK, bits, 0, NULL);
2461fd41f50Stb }
2471fd41f50Stb 
2481fd41f50Stb int
2491fd41f50Stb ssl_security_tickets(const SSL *ssl)
2501fd41f50Stb {
2511fd41f50Stb 	return ssl_security(ssl, SSL_SECOP_TICKET, 0, 0, NULL);
2521fd41f50Stb }
2531fd41f50Stb 
2541fd41f50Stb int
255072453d1Stb ssl_security_version(const SSL *ssl, int version)
25689b4969bStb {
257072453d1Stb 	return ssl_security(ssl, SSL_SECOP_VERSION, 0, version, NULL);
25889b4969bStb }
25989b4969bStb 
2601fd41f50Stb static int
2611fd41f50Stb ssl_security_cipher(const SSL *ssl, SSL_CIPHER *cipher, int secop)
2621fd41f50Stb {
2631fd41f50Stb 	return ssl_security(ssl, secop, cipher->strength_bits, 0, cipher);
2641fd41f50Stb }
2651fd41f50Stb 
2661fd41f50Stb int
2671fd41f50Stb ssl_security_cipher_check(const SSL *ssl, SSL_CIPHER *cipher)
2681fd41f50Stb {
2691fd41f50Stb 	return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_CHECK);
2701fd41f50Stb }
2711fd41f50Stb 
2721fd41f50Stb int
2731fd41f50Stb ssl_security_shared_cipher(const SSL *ssl, SSL_CIPHER *cipher)
2741fd41f50Stb {
2751fd41f50Stb 	return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SHARED);
2761fd41f50Stb }
2771fd41f50Stb 
2781fd41f50Stb int
2791fd41f50Stb ssl_security_supported_cipher(const SSL *ssl, SSL_CIPHER *cipher)
2801fd41f50Stb {
2811fd41f50Stb 	return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SUPPORTED);
2821fd41f50Stb }
2831fd41f50Stb 
28489b4969bStb int
2851bc539a7Stb ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh)
2861bc539a7Stb {
28768d7a0a5Stb 	int bits;
28868d7a0a5Stb 
28968d7a0a5Stb 	bits = DH_security_bits(dh);
29068d7a0a5Stb 
29168d7a0a5Stb 	return ssl_ctx_security(ctx, SSL_SECOP_TMP_DH, bits, 0, dh);
2921bc539a7Stb }
293da1f5ba3Stb 
2941bc539a7Stb int
2952c1036d8Stb ssl_security_dh(const SSL *ssl, DH *dh)
2962c1036d8Stb {
29768d7a0a5Stb 	int bits;
29868d7a0a5Stb 
29968d7a0a5Stb 	bits = DH_security_bits(dh);
30068d7a0a5Stb 
30168d7a0a5Stb 	return ssl_security(ssl, SSL_SECOP_TMP_DH, bits, 0, dh);
3022c1036d8Stb }
3035f8716e2Stb 
3045f8716e2Stb static int
3055f8716e2Stb ssl_cert_pubkey_security_bits(const X509 *x509)
3065f8716e2Stb {
3075f8716e2Stb 	EVP_PKEY *pkey;
3085f8716e2Stb 
3095f8716e2Stb 	if ((pkey = X509_get0_pubkey(x509)) == NULL)
3105f8716e2Stb 		return -1;
3115f8716e2Stb 
3125f8716e2Stb 	return EVP_PKEY_security_bits(pkey);
3135f8716e2Stb }
3145f8716e2Stb 
3155f8716e2Stb static int
31637d1243cStb ssl_security_cert_key(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
3175f8716e2Stb {
3185f8716e2Stb 	int security_bits;
3195f8716e2Stb 
3205f8716e2Stb 	security_bits = ssl_cert_pubkey_security_bits(x509);
3215f8716e2Stb 
3225f8716e2Stb 	if (ssl != NULL)
32337d1243cStb 		return ssl_security(ssl, secop, security_bits, 0, x509);
3245f8716e2Stb 
32537d1243cStb 	return ssl_ctx_security(ctx, secop, security_bits, 0, x509);
3265f8716e2Stb }
3275f8716e2Stb 
3285f8716e2Stb static int
32909837443Stb ssl_security_cert_sig_security_bits(X509 *x509, int *out_md_nid)
3305f8716e2Stb {
33109837443Stb 	int pkey_nid, security_bits;
33209837443Stb 	uint32_t flags;
3335f8716e2Stb 
33409837443Stb 	*out_md_nid = NID_undef;
3355f8716e2Stb 
33609837443Stb 	/*
33709837443Stb 	 * Returning -1 security bits makes the default security callback fail
33809837443Stb 	 * to match bonkers behavior in OpenSSL. This in turn lets a security
33909837443Stb 	 * callback override such failures.
34009837443Stb 	 */
34109837443Stb 	if (!X509_get_signature_info(x509, out_md_nid, &pkey_nid, &security_bits,
34209837443Stb 	    &flags))
34309837443Stb 		return -1;
34409837443Stb 	/*
34509837443Stb 	 * OpenSSL doesn't check flags. Test RSA-PSS certs we were provided have
34609837443Stb 	 * a salt length distinct from hash length and thus fail this check.
34709837443Stb 	 */
34809837443Stb 	if ((flags & X509_SIG_INFO_TLS) == 0)
3495f8716e2Stb 		return -1;
3505f8716e2Stb 
35109837443Stb 	/* Weird OpenSSL behavior only relevant for EdDSA certs in LibreSSL. */
35209837443Stb 	if (*out_md_nid == NID_undef)
35309837443Stb 		*out_md_nid = pkey_nid;
3545f8716e2Stb 
35509837443Stb 	return security_bits;
3565f8716e2Stb }
3575f8716e2Stb 
3585f8716e2Stb static int
35937d1243cStb ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
3605f8716e2Stb {
36109837443Stb 	int md_nid = NID_undef, security_bits = -1;
3625f8716e2Stb 
363e9f75676Stb 	/* Don't check signature if self signed. */
364e9f75676Stb 	if ((X509_get_extension_flags(x509) & EXFLAG_SS) != 0)
365e9f75676Stb 		return 1;
366e9f75676Stb 
36709837443Stb 	/*
36809837443Stb 	 * The default security callback fails on -1 security bits. It ignores
36909837443Stb 	 * the md_nid (aka version) argument we pass from here.
37009837443Stb 	 */
37109837443Stb 	security_bits = ssl_security_cert_sig_security_bits(x509, &md_nid);
3725f8716e2Stb 
3735f8716e2Stb 	if (ssl != NULL)
37437d1243cStb 		return ssl_security(ssl, secop, security_bits, md_nid, x509);
3755f8716e2Stb 
37637d1243cStb 	return ssl_ctx_security(ctx, secop, security_bits, md_nid, x509);
3775f8716e2Stb }
3785f8716e2Stb 
3795f8716e2Stb int
3805f8716e2Stb ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509,
3815f8716e2Stb     int is_ee, int *out_error)
3825f8716e2Stb {
3835f8716e2Stb 	int key_error, operation;
3845f8716e2Stb 
3855f8716e2Stb 	*out_error = 0;
3865f8716e2Stb 
3875f8716e2Stb 	if (is_ee) {
3885f8716e2Stb 		operation = SSL_SECOP_EE_KEY;
3895f8716e2Stb 		key_error = SSL_R_EE_KEY_TOO_SMALL;
3905f8716e2Stb 	} else {
3915f8716e2Stb 		operation = SSL_SECOP_CA_KEY;
3925f8716e2Stb 		key_error = SSL_R_CA_KEY_TOO_SMALL;
3935f8716e2Stb 	}
3945f8716e2Stb 
3955f8716e2Stb 	if (!ssl_security_cert_key(ctx, ssl, x509, operation)) {
3965f8716e2Stb 		*out_error = key_error;
3975f8716e2Stb 		return 0;
3985f8716e2Stb 	}
3995f8716e2Stb 
4005f8716e2Stb 	if (!ssl_security_cert_sig(ctx, ssl, x509, SSL_SECOP_CA_MD)) {
4015f8716e2Stb 		*out_error = SSL_R_CA_MD_TOO_WEAK;
4025f8716e2Stb 		return 0;
4035f8716e2Stb 	}
4045f8716e2Stb 
4055f8716e2Stb 	return 1;
4065f8716e2Stb }
4075f8716e2Stb 
4085f8716e2Stb /*
4095f8716e2Stb  * Check security of a chain. If |sk| includes the end entity certificate
4105f8716e2Stb  * then |x509| must be NULL.
4115f8716e2Stb  */
4125f8716e2Stb int
4135f8716e2Stb ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, X509 *x509,
4145f8716e2Stb     int *out_error)
4155f8716e2Stb {
4165f8716e2Stb 	int start_idx = 0;
4175f8716e2Stb 	int is_ee;
4185f8716e2Stb 	int i;
4195f8716e2Stb 
4205f8716e2Stb 	if (x509 == NULL) {
4215f8716e2Stb 		x509 = sk_X509_value(sk, 0);
4225f8716e2Stb 		start_idx = 1;
4235f8716e2Stb 	}
4245f8716e2Stb 
425cb99b402Stb 	is_ee = 1;
426cb99b402Stb 	if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error))
4275f8716e2Stb 		return 0;
4285f8716e2Stb 
429cb99b402Stb 	is_ee = 0;
4305f8716e2Stb 	for (i = start_idx; i < sk_X509_num(sk); i++) {
4315f8716e2Stb 		x509 = sk_X509_value(sk, i);
4325f8716e2Stb 
433cb99b402Stb 		if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error))
4345f8716e2Stb 			return 0;
4355f8716e2Stb 	}
4365f8716e2Stb 
4375f8716e2Stb 	return 1;
4385f8716e2Stb }
43913053e69Stb 
440051c5a6aStb static int
441051c5a6aStb ssl_security_group(const SSL *ssl, uint16_t group_id, int secop)
44213053e69Stb {
44313053e69Stb 	CBB cbb;
44413053e69Stb 	int bits, nid;
445c5270c5dStb 	uint8_t group[2];
44613053e69Stb 
447bd6ff868Stb 	memset(&cbb, 0, sizeof(cbb));
448bd6ff868Stb 
449c5270c5dStb 	if (!tls1_ec_group_id2bits(group_id, &bits))
450bd6ff868Stb 		goto err;
451c5270c5dStb 	if (!tls1_ec_group_id2nid(group_id, &nid))
452bd6ff868Stb 		goto err;
45313053e69Stb 
454c5270c5dStb 	if (!CBB_init_fixed(&cbb, group, sizeof(group)))
455bd6ff868Stb 		goto err;
456c5270c5dStb 	if (!CBB_add_u16(&cbb, group_id))
457bd6ff868Stb 		goto err;
45813053e69Stb 	if (!CBB_finish(&cbb, NULL, NULL))
459bd6ff868Stb 		goto err;
46013053e69Stb 
461051c5a6aStb 	return ssl_security(ssl, secop, bits, nid, group);
462bd6ff868Stb 
463bd6ff868Stb  err:
464bd6ff868Stb 	CBB_cleanup(&cbb);
465bd6ff868Stb 
466bd6ff868Stb 	return 0;
467051c5a6aStb }
468051c5a6aStb 
469051c5a6aStb int
470051c5a6aStb ssl_security_shared_group(const SSL *ssl, uint16_t group_id)
471051c5a6aStb {
472051c5a6aStb 	return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SHARED);
473051c5a6aStb }
474051c5a6aStb 
475051c5a6aStb int
476051c5a6aStb ssl_security_supported_group(const SSL *ssl, uint16_t group_id)
477051c5a6aStb {
478051c5a6aStb 	return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SUPPORTED);
47913053e69Stb }
480